authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-01-31 20:27:17+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-01-31 20:27:17+01:00
logc430e9afa7b050400b9703360a0af4ab824335ce
tree1a91f7abd8ca2c92100a713e5978c16cfe845a9c
parent4404c4d20094bb5021aac4a047cd33b6c24b9a9b

link: make Coff atoms fully owned by the linker


12 files changed, 350 insertions(+), 275 deletions(-)

src/Module.zig+3-3
...@@ -5274,7 +5274,7 @@ pub fn clearDecl(...@@ -5274,7 +5274,7 @@ pub fn clearDecl(
5274 // TODO instead of a union, put this memory trailing Decl objects,5274 // TODO instead of a union, put this memory trailing Decl objects,
5275 // and allow it to be variably sized.5275 // and allow it to be variably sized.
5276 decl.link = switch (mod.comp.bin_file.tag) {5276 decl.link = switch (mod.comp.bin_file.tag) {
5277 .coff => .{ .coff = link.File.Coff.Atom.empty },5277 .coff => .{ .coff = {} },
5278 .elf => .{ .elf = {} },5278 .elf => .{ .elf = {} },
5279 .macho => .{ .macho = {} },5279 .macho => .{ .macho = {} },
5280 .plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },5280 .plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
...@@ -5390,7 +5390,7 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void...@@ -5390,7 +5390,7 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void
5390 wasm.deleteExport(exp.link.wasm);5390 wasm.deleteExport(exp.link.wasm);
5391 }5391 }
5392 if (mod.comp.bin_file.cast(link.File.Coff)) |coff| {5392 if (mod.comp.bin_file.cast(link.File.Coff)) |coff| {
5393 coff.deleteExport(exp.link.coff);5393 coff.deleteDeclExport(decl_index, exp.options.name);
5394 }5394 }
5395 if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {5395 if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {
5396 failed_kv.value.destroy(mod.gpa);5396 failed_kv.value.destroy(mod.gpa);
...@@ -5694,7 +5694,7 @@ pub fn allocateNewDecl(...@@ -5694,7 +5694,7 @@ pub fn allocateNewDecl(
5694 .zir_decl_index = 0,5694 .zir_decl_index = 0,
5695 .src_scope = src_scope,5695 .src_scope = src_scope,
5696 .link = switch (mod.comp.bin_file.tag) {5696 .link = switch (mod.comp.bin_file.tag) {
5697 .coff => .{ .coff = link.File.Coff.Atom.empty },5697 .coff => .{ .coff = {} },
5698 .elf => .{ .elf = {} },5698 .elf => .{ .elf = {} },
5699 .macho => .{ .macho = {} },5699 .macho => .{ .macho = {} },
5700 .plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },5700 .plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
src/Sema.zig+1-1
...@@ -5565,7 +5565,7 @@ pub fn analyzeExport(...@@ -5565,7 +5565,7 @@ pub fn analyzeExport(
5565 },5565 },
5566 .src = src,5566 .src = src,
5567 .link = switch (mod.comp.bin_file.tag) {5567 .link = switch (mod.comp.bin_file.tag) {
5568 .coff => .{ .coff = .{} },5568 .coff => .{ .coff = {} },
5569 .elf => .{ .elf = {} },5569 .elf => .{ .elf = {} },
5570 .macho => .{ .macho = {} },5570 .macho => .{ .macho = {} },
5571 .plan9 => .{ .plan9 = null },5571 .plan9 => .{ .plan9 = null },
src/arch/aarch64/CodeGen.zig+26-16
...@@ -4019,15 +4019,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -4019,15 +4019,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
4019 .direct => .load_memory_ptr_direct,4019 .direct => .load_memory_ptr_direct,
4020 .import => unreachable,4020 .import => unreachable,
4021 };4021 };
4022 const mod = self.bin_file.options.module.?;
4023 const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
4024 const atom_index = switch (self.bin_file.tag) {4022 const atom_index = switch (self.bin_file.tag) {
4025 .macho => blk: {4023 .macho => blk: {
4026 const macho_file = self.bin_file.cast(link.File.MachO).?;4024 const macho_file = self.bin_file.cast(link.File.MachO).?;
4027 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);4025 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4028 break :blk macho_file.getAtom(atom).getSymbolIndex().?;4026 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
4029 },4027 },
4030 .coff => owner_decl.link.coff.getSymbolIndex().?,4028 .coff => blk: {
4029 const coff_file = self.bin_file.cast(link.File.Coff).?;
4030 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4031 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
4032 },
4031 else => unreachable, // unsupported target format4033 else => unreachable, // unsupported target format
4032 };4034 };
4033 _ = try self.addInst(.{4035 _ = try self.addInst(.{
...@@ -4322,11 +4324,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4322,11 +4324,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4322 },4324 },
4323 });4325 });
4324 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {4326 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
4325 try fn_owner_decl.link.coff.ensureInitialized(coff_file);4327 const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
4328 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
4326 try self.genSetReg(Type.initTag(.u64), .x30, .{4329 try self.genSetReg(Type.initTag(.u64), .x30, .{
4327 .linker_load = .{4330 .linker_load = .{
4328 .type = .got,4331 .type = .got,
4329 .sym_index = fn_owner_decl.link.coff.getSymbolIndex().?,4332 .sym_index = sym_index,
4330 },4333 },
4331 });4334 });
4332 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {4335 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
...@@ -5496,15 +5499,17 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5496,15 +5499,17 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5496 .direct => .load_memory_ptr_direct,5499 .direct => .load_memory_ptr_direct,
5497 .import => unreachable,5500 .import => unreachable,
5498 };5501 };
5499 const mod = self.bin_file.options.module.?;
5500 const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
5501 const atom_index = switch (self.bin_file.tag) {5502 const atom_index = switch (self.bin_file.tag) {
5502 .macho => blk: {5503 .macho => blk: {
5503 const macho_file = self.bin_file.cast(link.File.MachO).?;5504 const macho_file = self.bin_file.cast(link.File.MachO).?;
5504 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);5505 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5505 break :blk macho_file.getAtom(atom).getSymbolIndex().?;5506 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5506 },5507 },
5507 .coff => owner_decl.link.coff.getSymbolIndex().?,5508 .coff => blk: {
5509 const coff_file = self.bin_file.cast(link.File.Coff).?;
5510 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5511 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5512 },
5508 else => unreachable, // unsupported target format5513 else => unreachable, // unsupported target format
5509 };5514 };
5510 _ = try self.addInst(.{5515 _ = try self.addInst(.{
...@@ -5614,15 +5619,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5614,15 +5619,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5614 .direct => .load_memory_direct,5619 .direct => .load_memory_direct,
5615 .import => .load_memory_import,5620 .import => .load_memory_import,
5616 };5621 };
5617 const mod = self.bin_file.options.module.?;
5618 const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
5619 const atom_index = switch (self.bin_file.tag) {5622 const atom_index = switch (self.bin_file.tag) {
5620 .macho => blk: {5623 .macho => blk: {
5621 const macho_file = self.bin_file.cast(link.File.MachO).?;5624 const macho_file = self.bin_file.cast(link.File.MachO).?;
5622 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);5625 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5623 break :blk macho_file.getAtom(atom).getSymbolIndex().?;5626 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5624 },5627 },
5625 .coff => owner_decl.link.coff.getSymbolIndex().?,5628 .coff => blk: {
5629 const coff_file = self.bin_file.cast(link.File.Coff).?;
5630 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5631 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5632 },
5626 else => unreachable, // unsupported target format5633 else => unreachable, // unsupported target format
5627 };5634 };
5628 _ = try self.addInst(.{5635 _ = try self.addInst(.{
...@@ -5812,15 +5819,17 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5812,15 +5819,17 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5812 .direct => .load_memory_ptr_direct,5819 .direct => .load_memory_ptr_direct,
5813 .import => unreachable,5820 .import => unreachable,
5814 };5821 };
5815 const mod = self.bin_file.options.module.?;
5816 const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
5817 const atom_index = switch (self.bin_file.tag) {5822 const atom_index = switch (self.bin_file.tag) {
5818 .macho => blk: {5823 .macho => blk: {
5819 const macho_file = self.bin_file.cast(link.File.MachO).?;5824 const macho_file = self.bin_file.cast(link.File.MachO).?;
5820 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);5825 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5821 break :blk macho_file.getAtom(atom).getSymbolIndex().?;5826 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5822 },5827 },
5823 .coff => owner_decl.link.coff.getSymbolIndex().?,5828 .coff => blk: {
5829 const coff_file = self.bin_file.cast(link.File.Coff).?;
5830 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5831 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5832 },
5824 else => unreachable, // unsupported target format5833 else => unreachable, // unsupported target format
5825 };5834 };
5826 _ = try self.addInst(.{5835 _ = try self.addInst(.{
...@@ -6150,10 +6159,11 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne...@@ -6150,10 +6159,11 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
6150 .sym_index = sym_index,6159 .sym_index = sym_index,
6151 } };6160 } };
6152 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {6161 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
6153 try decl.link.coff.ensureInitialized(coff_file);6162 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);
6163 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
6154 return MCValue{ .linker_load = .{6164 return MCValue{ .linker_load = .{
6155 .type = .got,6165 .type = .got,
6156 .sym_index = decl.link.coff.getSymbolIndex().?,6166 .sym_index = sym_index,
6157 } };6167 } };
6158 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {6168 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
6159 try p9.seeDecl(decl_index);6169 try p9.seeDecl(decl_index);
src/arch/aarch64/Emit.zig+3-3
...@@ -919,7 +919,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -919,7 +919,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
919 },919 },
920 });920 });
921 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {921 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
922 const atom = coff_file.getAtomForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;922 const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
923 const target = switch (tag) {923 const target = switch (tag) {
924 .load_memory_got,924 .load_memory_got,
925 .load_memory_ptr_got,925 .load_memory_ptr_got,
...@@ -929,7 +929,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -929,7 +929,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
929 .load_memory_import => coff_file.getGlobalByIndex(data.sym_index),929 .load_memory_import => coff_file.getGlobalByIndex(data.sym_index),
930 else => unreachable,930 else => unreachable,
931 };931 };
932 try atom.addRelocation(coff_file, .{932 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
933 .target = target,933 .target = target,
934 .offset = offset,934 .offset = offset,
935 .addend = 0,935 .addend = 0,
...@@ -946,7 +946,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -946,7 +946,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
946 else => unreachable,946 else => unreachable,
947 },947 },
948 });948 });
949 try atom.addRelocation(coff_file, .{949 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
950 .target = target,950 .target = target,
951 .offset = offset + 4,951 .offset = offset + 4,
952 .addend = 0,952 .addend = 0,
src/arch/x86_64/CodeGen.zig+8-8
...@@ -2668,13 +2668,12 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue...@@ -2668,13 +2668,12 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue
2668 switch (ptr) {2668 switch (ptr) {
2669 .linker_load => |load_struct| {2669 .linker_load => |load_struct| {
2670 const abi_size = @intCast(u32, ptr_ty.abiSize(self.target.*));2670 const abi_size = @intCast(u32, ptr_ty.abiSize(self.target.*));
2671 const mod = self.bin_file.options.module.?;
2672 const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl);
2673 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {2671 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
2674 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);2672 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
2675 break :blk macho_file.getAtom(atom).getSymbolIndex().?;2673 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
2676 } else if (self.bin_file.cast(link.File.Coff)) |_| blk: {2674 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
2677 break :blk fn_owner_decl.link.coff.getSymbolIndex().?;2675 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
2676 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
2678 } else unreachable;2677 } else unreachable;
2679 const flags: u2 = switch (load_struct.type) {2678 const flags: u2 = switch (load_struct.type) {
2680 .got => 0b00,2679 .got => 0b00,
...@@ -4009,8 +4008,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4009,8 +4008,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4009 .data = .{ .imm = got_addr },4008 .data = .{ .imm = got_addr },
4010 });4009 });
4011 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {4010 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
4012 try fn_owner_decl.link.coff.ensureInitialized(coff_file);4011 const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
4013 const sym_index = fn_owner_decl.link.coff.getSymbolIndex().?;4012 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
4014 try self.genSetReg(Type.initTag(.usize), .rax, .{4013 try self.genSetReg(Type.initTag(.usize), .rax, .{
4015 .linker_load = .{4014 .linker_load = .{
4016 .type = .got,4015 .type = .got,
...@@ -6733,10 +6732,11 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne...@@ -6733,10 +6732,11 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
6733 .sym_index = sym_index,6732 .sym_index = sym_index,
6734 } };6733 } };
6735 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {6734 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
6736 try decl.link.coff.ensureInitialized(coff_file);6735 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);
6736 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
6737 return MCValue{ .linker_load = .{6737 return MCValue{ .linker_load = .{
6738 .type = .got,6738 .type = .got,
6739 .sym_index = decl.link.coff.getSymbolIndex().?,6739 .sym_index = sym_index,
6740 } };6740 } };
6741 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {6741 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
6742 try p9.seeDecl(decl_index);6742 try p9.seeDecl(decl_index);
src/arch/x86_64/Emit.zig+4-4
...@@ -1011,8 +1011,8 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1011,8 +1011,8 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1011 .length = 2,1011 .length = 2,
1012 });1012 });
1013 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {1013 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
1014 const atom = coff_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;1014 const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
1015 try atom.addRelocation(coff_file, .{1015 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
1016 .type = switch (ops.flags) {1016 .type = switch (ops.flags) {
1017 0b00 => .got,1017 0b00 => .got,
1018 0b01 => .direct,1018 0b01 => .direct,
...@@ -1152,9 +1152,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1152,9 +1152,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1152 });1152 });
1153 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {1153 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
1154 // Add relocation to the decl.1154 // Add relocation to the decl.
1155 const atom = coff_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;1155 const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
1156 const target = coff_file.getGlobalByIndex(relocation.sym_index);1156 const target = coff_file.getGlobalByIndex(relocation.sym_index);
1157 try atom.addRelocation(coff_file, .{1157 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
1158 .type = .direct,1158 .type = .direct,
1159 .target = target,1159 .target = target,
1160 .offset = offset,1160 .offset = offset,
src/link.zig+2-2
...@@ -263,7 +263,7 @@ pub const File = struct {...@@ -263,7 +263,7 @@ pub const File = struct {
263263
264 pub const LinkBlock = union {264 pub const LinkBlock = union {
265 elf: void,265 elf: void,
266 coff: Coff.Atom,266 coff: void,
267 macho: void,267 macho: void,
268 plan9: Plan9.DeclBlock,268 plan9: Plan9.DeclBlock,
269 c: void,269 c: void,
...@@ -285,7 +285,7 @@ pub const File = struct {...@@ -285,7 +285,7 @@ pub const File = struct {
285285
286 pub const Export = union {286 pub const Export = union {
287 elf: void,287 elf: void,
288 coff: Coff.Export,288 coff: void,
289 macho: void,289 macho: void,
290 plan9: Plan9.Export,290 plan9: Plan9.Export,
291 c: void,291 c: void,
src/link/Coff.zig+256-204
...@@ -79,13 +79,13 @@ entry_addr: ?u32 = null,...@@ -79,13 +79,13 @@ entry_addr: ?u32 = null,
79/// We store them here so that we can properly dispose of any allocated79/// We store them here so that we can properly dispose of any allocated
80/// memory within the atom in the incremental linker.80/// memory within the atom in the incremental linker.
81/// TODO consolidate this.81/// TODO consolidate this.
82decls: std.AutoHashMapUnmanaged(Module.Decl.Index, ?u16) = .{},82decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
8383
84/// List of atoms that are either synthetic or map directly to the Zig source program.84/// List of atoms that are either synthetic or map directly to the Zig source program.
85managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},85atoms: std.ArrayListUnmanaged(Atom) = .{},
8686
87/// Table of atoms indexed by the symbol index.87/// Table of atoms indexed by the symbol index.
88atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{},88atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{},
8989
90/// Table of unnamed constants associated with a parent `Decl`.90/// Table of unnamed constants associated with a parent `Decl`.
91/// We store them here so that we can free the constants whenever the `Decl`91/// We store them here so that we can free the constants whenever the `Decl`
...@@ -124,9 +124,9 @@ const Entry = struct {...@@ -124,9 +124,9 @@ const Entry = struct {
124 sym_index: u32,124 sym_index: u32,
125};125};
126126
127const RelocTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Relocation));127const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation));
128const BaseRelocationTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(u32));128const BaseRelocationTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32));
129const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom));129const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));
130130
131const default_file_alignment: u16 = 0x200;131const default_file_alignment: u16 = 0x200;
132const default_size_of_stack_reserve: u32 = 0x1000000;132const default_size_of_stack_reserve: u32 = 0x1000000;
...@@ -137,7 +137,7 @@ const default_size_of_heap_commit: u32 = 0x1000;...@@ -137,7 +137,7 @@ const default_size_of_heap_commit: u32 = 0x1000;
137const Section = struct {137const Section = struct {
138 header: coff.SectionHeader,138 header: coff.SectionHeader,
139139
140 last_atom: ?*Atom = null,140 last_atom_index: ?Atom.Index = null,
141141
142 /// A list of atoms that have surplus capacity. This list can have false142 /// A list of atoms that have surplus capacity. This list can have false
143 /// positives, as functions grow and shrink over time, only sometimes being added143 /// positives, as functions grow and shrink over time, only sometimes being added
...@@ -154,7 +154,34 @@ const Section = struct {...@@ -154,7 +154,34 @@ const Section = struct {
154 /// overcapacity can be negative. A simple way to have negative overcapacity is to154 /// overcapacity can be negative. A simple way to have negative overcapacity is to
155 /// allocate a fresh atom, which will have ideal capacity, and then grow it155 /// allocate a fresh atom, which will have ideal capacity, and then grow it
156 /// by 1 byte. It will then have -1 overcapacity.156 /// by 1 byte. It will then have -1 overcapacity.
157 free_list: std.ArrayListUnmanaged(*Atom) = .{},157 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
158};
159
160const DeclMetadata = struct {
161 atom: Atom.Index,
162 section: u16,
163 /// A list of all exports aliases of this Decl.
164 exports: std.ArrayListUnmanaged(u32) = .{},
165
166 fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 {
167 for (m.exports.items) |exp| {
168 if (mem.eql(u8, name, coff_file.getSymbolName(.{
169 .sym_index = exp,
170 .file = null,
171 }))) return exp;
172 }
173 return null;
174 }
175
176 fn getExportPtr(m: *DeclMetadata, coff_file: *Coff, name: []const u8) ?*u32 {
177 for (m.exports.items) |*exp| {
178 if (mem.eql(u8, name, coff_file.getSymbolName(.{
179 .sym_index = exp.*,
180 .file = null,
181 }))) return exp;
182 }
183 return null;
184 }
158};185};
159186
160pub const PtrWidth = enum {187pub const PtrWidth = enum {
...@@ -170,10 +197,6 @@ pub const PtrWidth = enum {...@@ -170,10 +197,6 @@ pub const PtrWidth = enum {
170};197};
171pub const SrcFn = void;198pub const SrcFn = void;
172199
173pub const Export = struct {
174 sym_index: ?u32 = null,
175};
176
177pub const SymbolWithLoc = struct {200pub const SymbolWithLoc = struct {
178 // Index into the respective symbol table.201 // Index into the respective symbol table.
179 sym_index: u32,202 sym_index: u32,
...@@ -271,11 +294,7 @@ pub fn deinit(self: *Coff) void {...@@ -271,11 +294,7 @@ pub fn deinit(self: *Coff) void {
271 }294 }
272 self.sections.deinit(gpa);295 self.sections.deinit(gpa);
273296
274 for (self.managed_atoms.items) |atom| {297 self.atoms.deinit(gpa);
275 gpa.destroy(atom);
276 }
277 self.managed_atoms.deinit(gpa);
278
279 self.locals.deinit(gpa);298 self.locals.deinit(gpa);
280 self.globals.deinit(gpa);299 self.globals.deinit(gpa);
281300
...@@ -297,7 +316,15 @@ pub fn deinit(self: *Coff) void {...@@ -297,7 +316,15 @@ pub fn deinit(self: *Coff) void {
297 self.imports.deinit(gpa);316 self.imports.deinit(gpa);
298 self.imports_free_list.deinit(gpa);317 self.imports_free_list.deinit(gpa);
299 self.imports_table.deinit(gpa);318 self.imports_table.deinit(gpa);
300 self.decls.deinit(gpa);319
320 {
321 var it = self.decls.iterator();
322 while (it.next()) |entry| {
323 entry.value_ptr.exports.deinit(gpa);
324 }
325 self.decls.deinit(gpa);
326 }
327
301 self.atom_by_index_table.deinit(gpa);328 self.atom_by_index_table.deinit(gpa);
302329
303 {330 {
...@@ -461,17 +488,18 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void {...@@ -461,17 +488,18 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void {
461 // TODO: enforce order by increasing VM addresses in self.sections container.488 // TODO: enforce order by increasing VM addresses in self.sections container.
462 // This is required by the loader anyhow as far as I can tell.489 // This is required by the loader anyhow as far as I can tell.
463 for (self.sections.items(.header)[sect_id + 1 ..]) |*next_header, next_sect_id| {490 for (self.sections.items(.header)[sect_id + 1 ..]) |*next_header, next_sect_id| {
464 const maybe_last_atom = &self.sections.items(.last_atom)[sect_id + 1 + next_sect_id];491 const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id + 1 + next_sect_id];
465 next_header.virtual_address += diff;492 next_header.virtual_address += diff;
466493
467 if (maybe_last_atom.*) |last_atom| {494 if (maybe_last_atom_index) |last_atom_index| {
468 var atom = last_atom;495 var atom_index = last_atom_index;
469 while (true) {496 while (true) {
497 const atom = self.getAtom(atom_index);
470 const sym = atom.getSymbolPtr(self);498 const sym = atom.getSymbolPtr(self);
471 sym.value += diff;499 sym.value += diff;
472500
473 if (atom.prev) |prev| {501 if (atom.prev_index) |prev_index| {
474 atom = prev;502 atom_index = prev_index;
475 } else break;503 } else break;
476 }504 }
477 }505 }
...@@ -480,14 +508,15 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void {...@@ -480,14 +508,15 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void {
480 header.virtual_size = increased_size;508 header.virtual_size = increased_size;
481}509}
482510
483fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u32 {511fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 {
484 const tracy = trace(@src());512 const tracy = trace(@src());
485 defer tracy.end();513 defer tracy.end();
486514
515 const atom = self.getAtom(atom_index);
487 const sect_id = @enumToInt(atom.getSymbol(self).section_number) - 1;516 const sect_id = @enumToInt(atom.getSymbol(self).section_number) - 1;
488 const header = &self.sections.items(.header)[sect_id];517 const header = &self.sections.items(.header)[sect_id];
489 const free_list = &self.sections.items(.free_list)[sect_id];518 const free_list = &self.sections.items(.free_list)[sect_id];
490 const maybe_last_atom = &self.sections.items(.last_atom)[sect_id];519 const maybe_last_atom_index = &self.sections.items(.last_atom_index)[sect_id];
491 const new_atom_ideal_capacity = if (header.isCode()) padToIdeal(new_atom_size) else new_atom_size;520 const new_atom_ideal_capacity = if (header.isCode()) padToIdeal(new_atom_size) else new_atom_size;
492521
493 // We use these to indicate our intention to update metadata, placing the new atom,522 // We use these to indicate our intention to update metadata, placing the new atom,
...@@ -495,7 +524,7 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u...@@ -495,7 +524,7 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u
495 // It would be simpler to do it inside the for loop below, but that would cause a524 // It would be simpler to do it inside the for loop below, but that would cause a
496 // problem if an error was returned later in the function. So this action525 // problem if an error was returned later in the function. So this action
497 // is actually carried out at the end of the function, when errors are no longer possible.526 // is actually carried out at the end of the function, when errors are no longer possible.
498 var atom_placement: ?*Atom = null;527 var atom_placement: ?Atom.Index = null;
499 var free_list_removal: ?usize = null;528 var free_list_removal: ?usize = null;
500529
501 // First we look for an appropriately sized free list node.530 // First we look for an appropriately sized free list node.
...@@ -503,7 +532,8 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u...@@ -503,7 +532,8 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u
503 var vaddr = blk: {532 var vaddr = blk: {
504 var i: usize = 0;533 var i: usize = 0;
505 while (i < free_list.items.len) {534 while (i < free_list.items.len) {
506 const big_atom = free_list.items[i];535 const big_atom_index = free_list.items[i];
536 const big_atom = self.getAtom(big_atom_index);
507 // We now have a pointer to a live atom that has too much capacity.537 // We now have a pointer to a live atom that has too much capacity.
508 // Is it enough that we could fit this new atom?538 // Is it enough that we could fit this new atom?
509 const sym = big_atom.getSymbol(self);539 const sym = big_atom.getSymbol(self);
...@@ -531,34 +561,43 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u...@@ -531,34 +561,43 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u
531 const keep_free_list_node = remaining_capacity >= min_text_capacity;561 const keep_free_list_node = remaining_capacity >= min_text_capacity;
532562
533 // Set up the metadata to be updated, after errors are no longer possible.563 // Set up the metadata to be updated, after errors are no longer possible.
534 atom_placement = big_atom;564 atom_placement = big_atom_index;
535 if (!keep_free_list_node) {565 if (!keep_free_list_node) {
536 free_list_removal = i;566 free_list_removal = i;
537 }567 }
538 break :blk new_start_vaddr;568 break :blk new_start_vaddr;
539 } else if (maybe_last_atom.*) |last| {569 } else if (maybe_last_atom_index.*) |last_index| {
570 const last = self.getAtom(last_index);
540 const last_symbol = last.getSymbol(self);571 const last_symbol = last.getSymbol(self);
541 const ideal_capacity = if (header.isCode()) padToIdeal(last.size) else last.size;572 const ideal_capacity = if (header.isCode()) padToIdeal(last.size) else last.size;
542 const ideal_capacity_end_vaddr = last_symbol.value + ideal_capacity;573 const ideal_capacity_end_vaddr = last_symbol.value + ideal_capacity;
543 const new_start_vaddr = mem.alignForwardGeneric(u32, ideal_capacity_end_vaddr, alignment);574 const new_start_vaddr = mem.alignForwardGeneric(u32, ideal_capacity_end_vaddr, alignment);
544 atom_placement = last;575 atom_placement = last_index;
545 break :blk new_start_vaddr;576 break :blk new_start_vaddr;
546 } else {577 } else {
547 break :blk mem.alignForwardGeneric(u32, header.virtual_address, alignment);578 break :blk mem.alignForwardGeneric(u32, header.virtual_address, alignment);
548 }579 }
549 };580 };
550581
551 const expand_section = atom_placement == null or atom_placement.?.next == null;582 const expand_section = if (atom_placement) |placement_index|
583 self.getAtom(placement_index).next_index == null
584 else
585 true;
552 if (expand_section) {586 if (expand_section) {
553 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);587 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);
554 const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address;588 const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address;
555 if (needed_size > sect_capacity) {589 if (needed_size > sect_capacity) {
556 const new_offset = self.findFreeSpace(needed_size, default_file_alignment);590 const new_offset = self.findFreeSpace(needed_size, default_file_alignment);
557 const current_size = if (maybe_last_atom.*) |last_atom| blk: {591 const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: {
592 const last_atom = self.getAtom(last_atom_index);
558 const sym = last_atom.getSymbol(self);593 const sym = last_atom.getSymbol(self);
559 break :blk (sym.value + last_atom.size) - header.virtual_address;594 break :blk (sym.value + last_atom.size) - header.virtual_address;
560 } else 0;595 } else 0;
561 log.debug("moving {s} from 0x{x} to 0x{x}", .{ self.getSectionName(header), header.pointer_to_raw_data, new_offset });596 log.debug("moving {s} from 0x{x} to 0x{x}", .{
597 self.getSectionName(header),
598 header.pointer_to_raw_data,
599 new_offset,
600 });
562 const amt = try self.base.file.?.copyRangeAll(601 const amt = try self.base.file.?.copyRangeAll(
563 header.pointer_to_raw_data,602 header.pointer_to_raw_data,
564 self.base.file.?,603 self.base.file.?,
...@@ -577,26 +616,34 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u...@@ -577,26 +616,34 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u
577616
578 header.virtual_size = @max(header.virtual_size, needed_size);617 header.virtual_size = @max(header.virtual_size, needed_size);
579 header.size_of_raw_data = needed_size;618 header.size_of_raw_data = needed_size;
580 maybe_last_atom.* = atom;619 maybe_last_atom_index.* = atom_index;
581 }620 }
582621
583 atom.size = new_atom_size;622 {
584 atom.alignment = alignment;623 const atom_ptr = self.getAtomPtr(atom_index);
624 atom_ptr.size = new_atom_size;
625 atom_ptr.alignment = alignment;
626 }
585627
586 if (atom.prev) |prev| {628 if (atom.prev_index) |prev_index| {
587 prev.next = atom.next;629 const prev = self.getAtomPtr(prev_index);
630 prev.next_index = atom.next_index;
588 }631 }
589 if (atom.next) |next| {632 if (atom.next_index) |next_index| {
590 next.prev = atom.prev;633 const next = self.getAtomPtr(next_index);
634 next.prev_index = atom.prev_index;
591 }635 }
592636
593 if (atom_placement) |big_atom| {637 if (atom_placement) |big_atom_index| {
594 atom.prev = big_atom;638 const big_atom = self.getAtomPtr(big_atom_index);
595 atom.next = big_atom.next;639 const atom_ptr = self.getAtomPtr(atom_index);
596 big_atom.next = atom;640 atom_ptr.prev_index = big_atom_index;
641 atom_ptr.next_index = big_atom.next_index;
642 big_atom.next_index = atom_index;
597 } else {643 } else {
598 atom.prev = null;644 const atom_ptr = self.getAtomPtr(atom_index);
599 atom.next = null;645 atom_ptr.prev_index = null;
646 atom_ptr.next_index = null;
600 }647 }
601 if (free_list_removal) |i| {648 if (free_list_removal) |i| {
602 _ = free_list.swapRemove(i);649 _ = free_list.swapRemove(i);
...@@ -701,24 +748,37 @@ pub fn allocateImportEntry(self: *Coff, target: SymbolWithLoc) !u32 {...@@ -701,24 +748,37 @@ pub fn allocateImportEntry(self: *Coff, target: SymbolWithLoc) !u32 {
701 return index;748 return index;
702}749}
703750
704fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom {751pub fn createAtom(self: *Coff) !Atom.Index {
705 const gpa = self.base.allocator;752 const gpa = self.base.allocator;
706 const atom = try gpa.create(Atom);753 const atom_index = @intCast(Atom.Index, self.atoms.items.len);
707 errdefer gpa.destroy(atom);754 const atom = try self.atoms.addOne(gpa);
708 atom.* = Atom.empty;755 const sym_index = try self.allocateSymbol();
709 try atom.ensureInitialized(self);756 try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
757 atom.* = .{
758 .sym_index = sym_index,
759 .file = null,
760 .size = 0,
761 .alignment = 0,
762 .prev_index = null,
763 .next_index = null,
764 };
765 log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, atom_index });
766 return atom_index;
767}
768
769fn createGotAtom(self: *Coff, target: SymbolWithLoc) !Atom.Index {
770 const atom_index = try self.createAtom();
771 const atom = self.getAtomPtr(atom_index);
710 atom.size = @sizeOf(u64);772 atom.size = @sizeOf(u64);
711 atom.alignment = @alignOf(u64);773 atom.alignment = @alignOf(u64);
712774
713 try self.managed_atoms.append(gpa, atom);
714
715 const sym = atom.getSymbolPtr(self);775 const sym = atom.getSymbolPtr(self);
716 sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1);776 sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1);
717 sym.value = try self.allocateAtom(atom, atom.size, atom.alignment);777 sym.value = try self.allocateAtom(atom_index, atom.size, atom.alignment);
718778
719 log.debug("allocated GOT atom at 0x{x}", .{sym.value});779 log.debug("allocated GOT atom at 0x{x}", .{sym.value});
720780
721 try atom.addRelocation(self, .{781 try Atom.addRelocation(self, atom_index, .{
722 .type = .direct,782 .type = .direct,
723 .target = target,783 .target = target,
724 .offset = 0,784 .offset = 0,
...@@ -732,49 +792,46 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom {...@@ -732,49 +792,46 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom {
732 .UNDEFINED => @panic("TODO generate a binding for undefined GOT target"),792 .UNDEFINED => @panic("TODO generate a binding for undefined GOT target"),
733 .ABSOLUTE => {},793 .ABSOLUTE => {},
734 .DEBUG => unreachable, // not possible794 .DEBUG => unreachable, // not possible
735 else => try atom.addBaseRelocation(self, 0),795 else => try Atom.addBaseRelocation(self, atom_index, 0),
736 }796 }
737797
738 return atom;798 return atom_index;
739}799}
740800
741fn createImportAtom(self: *Coff) !*Atom {801fn createImportAtom(self: *Coff) !Atom.Index {
742 const gpa = self.base.allocator;802 const atom_index = try self.createAtom();
743 const atom = try gpa.create(Atom);803 const atom = self.getAtomPtr(atom_index);
744 errdefer gpa.destroy(atom);
745 atom.* = Atom.empty;
746 try atom.ensureInitialized(self);
747 atom.size = @sizeOf(u64);804 atom.size = @sizeOf(u64);
748 atom.alignment = @alignOf(u64);805 atom.alignment = @alignOf(u64);
749806
750 try self.managed_atoms.append(gpa, atom);
751
752 const sym = atom.getSymbolPtr(self);807 const sym = atom.getSymbolPtr(self);
753 sym.section_number = @intToEnum(coff.SectionNumber, self.idata_section_index.? + 1);808 sym.section_number = @intToEnum(coff.SectionNumber, self.idata_section_index.? + 1);
754 sym.value = try self.allocateAtom(atom, atom.size, atom.alignment);809 sym.value = try self.allocateAtom(atom_index, atom.size, atom.alignment);
755810
756 log.debug("allocated import atom at 0x{x}", .{sym.value});811 log.debug("allocated import atom at 0x{x}", .{sym.value});
757812
758 return atom;813 return atom_index;
759}814}
760815
761fn growAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u32 {816fn growAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 {
817 const atom = self.getAtom(atom_index);
762 const sym = atom.getSymbol(self);818 const sym = atom.getSymbol(self);
763 const align_ok = mem.alignBackwardGeneric(u32, sym.value, alignment) == sym.value;819 const align_ok = mem.alignBackwardGeneric(u32, sym.value, alignment) == sym.value;
764 const need_realloc = !align_ok or new_atom_size > atom.capacity(self);820 const need_realloc = !align_ok or new_atom_size > atom.capacity(self);
765 if (!need_realloc) return sym.value;821 if (!need_realloc) return sym.value;
766 return self.allocateAtom(atom, new_atom_size, alignment);822 return self.allocateAtom(atom_index, new_atom_size, alignment);
767}823}
768824
769fn shrinkAtom(self: *Coff, atom: *Atom, new_block_size: u32) void {825fn shrinkAtom(self: *Coff, atom_index: Atom.Index, new_block_size: u32) void {
770 _ = self;826 _ = self;
771 _ = atom;827 _ = atom_index;
772 _ = new_block_size;828 _ = new_block_size;
773 // TODO check the new capacity, and if it crosses the size threshold into a big enough829 // TODO check the new capacity, and if it crosses the size threshold into a big enough
774 // capacity, insert a free list node for it.830 // capacity, insert a free list node for it.
775}831}
776832
777fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void {833fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []const u8) !void {
834 const atom = self.getAtom(atom_index);
778 const sym = atom.getSymbol(self);835 const sym = atom.getSymbol(self);
779 const section = self.sections.get(@enumToInt(sym.section_number) - 1);836 const section = self.sections.get(@enumToInt(sym.section_number) - 1);
780 const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address;837 const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address;
...@@ -784,18 +841,18 @@ fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void {...@@ -784,18 +841,18 @@ fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void {
784 file_offset + code.len,841 file_offset + code.len,
785 });842 });
786 try self.base.file.?.pwriteAll(code, file_offset);843 try self.base.file.?.pwriteAll(code, file_offset);
787 try self.resolveRelocs(atom);844 try self.resolveRelocs(atom_index);
788}845}
789846
790fn writePtrWidthAtom(self: *Coff, atom: *Atom) !void {847fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void {
791 switch (self.ptr_width) {848 switch (self.ptr_width) {
792 .p32 => {849 .p32 => {
793 var buffer: [@sizeOf(u32)]u8 = [_]u8{0} ** @sizeOf(u32);850 var buffer: [@sizeOf(u32)]u8 = [_]u8{0} ** @sizeOf(u32);
794 try self.writeAtom(atom, &buffer);851 try self.writeAtom(atom_index, &buffer);
795 },852 },
796 .p64 => {853 .p64 => {
797 var buffer: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64);854 var buffer: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64);
798 try self.writeAtom(atom, &buffer);855 try self.writeAtom(atom_index, &buffer);
799 },856 },
800 }857 }
801}858}
...@@ -815,7 +872,8 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {...@@ -815,7 +872,8 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {
815 var it = self.relocs.valueIterator();872 var it = self.relocs.valueIterator();
816 while (it.next()) |relocs| {873 while (it.next()) |relocs| {
817 for (relocs.items) |*reloc| {874 for (relocs.items) |*reloc| {
818 const target_atom = reloc.getTargetAtom(self) orelse continue;875 const target_atom_index = reloc.getTargetAtomIndex(self) orelse continue;
876 const target_atom = self.getAtom(target_atom_index);
819 const target_sym = target_atom.getSymbol(self);877 const target_sym = target_atom.getSymbol(self);
820 if (target_sym.value < addr) continue;878 if (target_sym.value < addr) continue;
821 reloc.dirty = true;879 reloc.dirty = true;
...@@ -823,24 +881,26 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {...@@ -823,24 +881,26 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {
823 }881 }
824}882}
825883
826fn resolveRelocs(self: *Coff, atom: *Atom) !void {884fn resolveRelocs(self: *Coff, atom_index: Atom.Index) !void {
827 const relocs = self.relocs.get(atom) orelse return;885 const relocs = self.relocs.get(atom_index) orelse return;
828886
829 log.debug("relocating '{s}'", .{atom.getName(self)});887 log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)});
830888
831 for (relocs.items) |*reloc| {889 for (relocs.items) |*reloc| {
832 if (!reloc.dirty) continue;890 if (!reloc.dirty) continue;
833 try reloc.resolve(atom, self);891 try reloc.resolve(atom_index, self);
834 }892 }
835}893}
836894
837fn freeAtom(self: *Coff, atom: *Atom) void {895fn freeAtom(self: *Coff, atom_index: Atom.Index) void {
838 log.debug("freeAtom {*}", .{atom});896 log.debug("freeAtom {d}", .{atom_index});
897
898 const gpa = self.base.allocator;
839899
840 // Remove any relocs and base relocs associated with this Atom900 // Remove any relocs and base relocs associated with this Atom
841 self.freeRelocationsForAtom(atom);901 Atom.freeRelocations(self, atom_index);
842902
843 const gpa = self.base.allocator;903 const atom = self.getAtom(atom_index);
844 const sym = atom.getSymbol(self);904 const sym = atom.getSymbol(self);
845 const sect_id = @enumToInt(sym.section_number) - 1;905 const sect_id = @enumToInt(sym.section_number) - 1;
846 const free_list = &self.sections.items(.free_list)[sect_id];906 const free_list = &self.sections.items(.free_list)[sect_id];
...@@ -849,45 +909,46 @@ fn freeAtom(self: *Coff, atom: *Atom) void {...@@ -849,45 +909,46 @@ fn freeAtom(self: *Coff, atom: *Atom) void {
849 var i: usize = 0;909 var i: usize = 0;
850 // TODO turn free_list into a hash map910 // TODO turn free_list into a hash map
851 while (i < free_list.items.len) {911 while (i < free_list.items.len) {
852 if (free_list.items[i] == atom) {912 if (free_list.items[i] == atom_index) {
853 _ = free_list.swapRemove(i);913 _ = free_list.swapRemove(i);
854 continue;914 continue;
855 }915 }
856 if (free_list.items[i] == atom.prev) {916 if (free_list.items[i] == atom.prev_index) {
857 already_have_free_list_node = true;917 already_have_free_list_node = true;
858 }918 }
859 i += 1;919 i += 1;
860 }920 }
861 }921 }
862922
863 const maybe_last_atom = &self.sections.items(.last_atom)[sect_id];923 const maybe_last_atom_index = &self.sections.items(.last_atom_index)[sect_id];
864 if (maybe_last_atom.*) |last_atom| {924 if (maybe_last_atom_index.*) |last_atom_index| {
865 if (last_atom == atom) {925 if (last_atom_index == atom_index) {
866 if (atom.prev) |prev| {926 if (atom.prev_index) |prev_index| {
867 // TODO shrink the section size here927 // TODO shrink the section size here
868 maybe_last_atom.* = prev;928 maybe_last_atom_index.* = prev_index;
869 } else {929 } else {
870 maybe_last_atom.* = null;930 maybe_last_atom_index.* = null;
871 }931 }
872 }932 }
873 }933 }
874934
875 if (atom.prev) |prev| {935 if (atom.prev_index) |prev_index| {
876 prev.next = atom.next;936 const prev = self.getAtomPtr(prev_index);
937 prev.next_index = atom.next_index;
877938
878 if (!already_have_free_list_node and prev.freeListEligible(self)) {939 if (!already_have_free_list_node and prev.*.freeListEligible(self)) {
879 // The free list is heuristics, it doesn't have to be perfect, so we can940 // The free list is heuristics, it doesn't have to be perfect, so we can
880 // ignore the OOM here.941 // ignore the OOM here.
881 free_list.append(gpa, prev) catch {};942 free_list.append(gpa, prev_index) catch {};
882 }943 }
883 } else {944 } else {
884 atom.prev = null;945 self.getAtomPtr(atom_index).prev_index = null;
885 }946 }
886947
887 if (atom.next) |next| {948 if (atom.next_index) |next_index| {
888 next.prev = atom.prev;949 self.getAtomPtr(next_index).prev_index = atom.prev_index;
889 } else {950 } else {
890 atom.next = null;951 self.getAtomPtr(atom_index).next_index = null;
891 }952 }
892953
893 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.954 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
...@@ -910,7 +971,7 @@ fn freeAtom(self: *Coff, atom: *Atom) void {...@@ -910,7 +971,7 @@ fn freeAtom(self: *Coff, atom: *Atom) void {
910 self.locals.items[sym_index].section_number = .UNDEFINED;971 self.locals.items[sym_index].section_number = .UNDEFINED;
911 _ = self.atom_by_index_table.remove(sym_index);972 _ = self.atom_by_index_table.remove(sym_index);
912 log.debug(" adding local symbol index {d} to free list", .{sym_index});973 log.debug(" adding local symbol index {d} to free list", .{sym_index});
913 atom.sym_index = 0;974 self.getAtomPtr(atom_index).sym_index = 0;
914}975}
915976
916pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {977pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
...@@ -927,15 +988,10 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live...@@ -927,15 +988,10 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
927988
928 const decl_index = func.owner_decl;989 const decl_index = func.owner_decl;
929 const decl = module.declPtr(decl_index);990 const decl = module.declPtr(decl_index);
930 const atom = &decl.link.coff;991
931 try atom.ensureInitialized(self);992 const atom_index = try self.getOrCreateAtomForDecl(decl_index);
932 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);993 self.freeUnnamedConsts(decl_index);
933 if (gop.found_existing) {994 Atom.freeRelocations(self, atom_index);
934 self.freeUnnamedConsts(decl_index);
935 self.freeRelocationsForAtom(&decl.link.coff);
936 } else {
937 gop.value_ptr.* = null;
938 }
939995
940 var code_buffer = std.ArrayList(u8).init(self.base.allocator);996 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
941 defer code_buffer.deinit();997 defer code_buffer.deinit();
...@@ -979,11 +1035,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In...@@ -979,11 +1035,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
979 }1035 }
980 const unnamed_consts = gop.value_ptr;1036 const unnamed_consts = gop.value_ptr;
9811037
982 const atom = try gpa.create(Atom);1038 const atom_index = try self.createAtom();
983 errdefer gpa.destroy(atom);1039 const atom = self.getAtomPtr(atom_index);
984 atom.* = Atom.empty;
985 try atom.ensureInitialized(self);
986 try self.managed_atoms.append(gpa, atom);
9871040
988 const sym_name = blk: {1041 const sym_name = blk: {
989 const decl_name = try decl.getFullyQualifiedName(mod);1042 const decl_name = try decl.getFullyQualifiedName(mod);
...@@ -1012,15 +1065,15 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In...@@ -1012,15 +1065,15 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
1012 const required_alignment = tv.ty.abiAlignment(self.base.options.target);1065 const required_alignment = tv.ty.abiAlignment(self.base.options.target);
1013 atom.alignment = required_alignment;1066 atom.alignment = required_alignment;
1014 atom.size = @intCast(u32, code.len);1067 atom.size = @intCast(u32, code.len);
1015 atom.getSymbolPtr(self).value = try self.allocateAtom(atom, atom.size, atom.alignment);1068 atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, atom.alignment);
1016 errdefer self.freeAtom(atom);1069 errdefer self.freeAtom(atom_index);
10171070
1018 try unnamed_consts.append(gpa, atom);1071 try unnamed_consts.append(gpa, atom_index);
10191072
1020 log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, atom.getSymbol(self).value });1073 log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, atom.getSymbol(self).value });
1021 log.debug(" (required alignment 0x{x})", .{required_alignment});1074 log.debug(" (required alignment 0x{x})", .{required_alignment});
10221075
1023 try self.writeAtom(atom, code);1076 try self.writeAtom(atom_index, code);
10241077
1025 return atom.getSymbolIndex().?;1078 return atom.getSymbolIndex().?;
1026}1079}
...@@ -1047,14 +1100,9 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !...@@ -1047,14 +1100,9 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
1047 }1100 }
1048 }1101 }
10491102
1050 const atom = &decl.link.coff;1103 const atom_index = try self.getOrCreateAtomForDecl(decl_index);
1051 try atom.ensureInitialized(self);1104 Atom.freeRelocations(self, atom_index);
1052 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);1105 const atom = self.getAtom(atom_index);
1053 if (gop.found_existing) {
1054 self.freeRelocationsForAtom(atom);
1055 } else {
1056 gop.value_ptr.* = null;
1057 }
10581106
1059 var code_buffer = std.ArrayList(u8).init(self.base.allocator);1107 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
1060 defer code_buffer.deinit();1108 defer code_buffer.deinit();
...@@ -1064,7 +1112,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !...@@ -1064,7 +1112,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
1064 .ty = decl.ty,1112 .ty = decl.ty,
1065 .val = decl_val,1113 .val = decl_val,
1066 }, &code_buffer, .none, .{1114 }, &code_buffer, .none, .{
1067 .parent_atom_index = decl.link.coff.getSymbolIndex().?,1115 .parent_atom_index = atom.getSymbolIndex().?,
1068 });1116 });
1069 const code = switch (res) {1117 const code = switch (res) {
1070 .ok => code_buffer.items,1118 .ok => code_buffer.items,
...@@ -1082,7 +1130,20 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !...@@ -1082,7 +1130,20 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
1082 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));1130 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
1083}1131}
10841132
1085fn getDeclOutputSection(self: *Coff, decl: *Module.Decl) u16 {1133pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {
1134 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
1135 if (!gop.found_existing) {
1136 gop.value_ptr.* = .{
1137 .atom = try self.createAtom(),
1138 .section = self.getDeclOutputSection(decl_index),
1139 .exports = .{},
1140 };
1141 }
1142 return gop.value_ptr.atom;
1143}
1144
1145fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
1146 const decl = self.base.options.module.?.declPtr(decl_index);
1086 const ty = decl.ty;1147 const ty = decl.ty;
1087 const zig_ty = ty.zigTypeTag();1148 const zig_ty = ty.zigTypeTag();
1088 const val = decl.val;1149 const val = decl.val;
...@@ -1117,14 +1178,11 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8,...@@ -1117,14 +1178,11 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8,
1117 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });1178 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
1118 const required_alignment = decl.getAlignment(self.base.options.target);1179 const required_alignment = decl.getAlignment(self.base.options.target);
11191180
1120 const decl_ptr = self.decls.getPtr(decl_index).?;1181 const decl_metadata = self.decls.get(decl_index).?;
1121 if (decl_ptr.* == null) {1182 const atom_index = decl_metadata.atom;
1122 decl_ptr.* = self.getDeclOutputSection(decl);1183 const atom = self.getAtom(atom_index);
1123 }1184 const sect_index = decl_metadata.section;
1124 const sect_index = decl_ptr.*.?;
1125
1126 const code_len = @intCast(u32, code.len);1185 const code_len = @intCast(u32, code.len);
1127 const atom = &decl.link.coff;
11281186
1129 if (atom.size != 0) {1187 if (atom.size != 0) {
1130 const sym = atom.getSymbolPtr(self);1188 const sym = atom.getSymbolPtr(self);
...@@ -1135,7 +1193,7 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8,...@@ -1135,7 +1193,7 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8,
1135 const capacity = atom.capacity(self);1193 const capacity = atom.capacity(self);
1136 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);1194 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);
1137 if (need_realloc) {1195 if (need_realloc) {
1138 const vaddr = try self.growAtom(atom, code_len, required_alignment);1196 const vaddr = try self.growAtom(atom_index, code_len, required_alignment);
1139 log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, sym.value, vaddr });1197 log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, sym.value, vaddr });
1140 log.debug(" (required alignment 0x{x}", .{required_alignment});1198 log.debug(" (required alignment 0x{x}", .{required_alignment});
11411199
...@@ -1143,49 +1201,43 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8,...@@ -1143,49 +1201,43 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8,
1143 sym.value = vaddr;1201 sym.value = vaddr;
1144 log.debug(" (updating GOT entry)", .{});1202 log.debug(" (updating GOT entry)", .{});
1145 const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null };1203 const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null };
1146 const got_atom = self.getGotAtomForSymbol(got_target).?;1204 const got_atom_index = self.getGotAtomIndexForSymbol(got_target).?;
1147 self.markRelocsDirtyByTarget(got_target);1205 self.markRelocsDirtyByTarget(got_target);
1148 try self.writePtrWidthAtom(got_atom);1206 try self.writePtrWidthAtom(got_atom_index);
1149 }1207 }
1150 } else if (code_len < atom.size) {1208 } else if (code_len < atom.size) {
1151 self.shrinkAtom(atom, code_len);1209 self.shrinkAtom(atom_index, code_len);
1152 }1210 }
1153 atom.size = code_len;1211 self.getAtomPtr(atom_index).size = code_len;
1154 } else {1212 } else {
1155 const sym = atom.getSymbolPtr(self);1213 const sym = atom.getSymbolPtr(self);
1156 try self.setSymbolName(sym, decl_name);1214 try self.setSymbolName(sym, decl_name);
1157 sym.section_number = @intToEnum(coff.SectionNumber, sect_index + 1);1215 sym.section_number = @intToEnum(coff.SectionNumber, sect_index + 1);
1158 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };1216 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
11591217
1160 const vaddr = try self.allocateAtom(atom, code_len, required_alignment);1218 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
1161 errdefer self.freeAtom(atom);1219 errdefer self.freeAtom(atom_index);
1162 log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, vaddr });1220 log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, vaddr });
1163 atom.size = code_len;1221 self.getAtomPtr(atom_index).size = code_len;
1164 sym.value = vaddr;1222 sym.value = vaddr;
11651223
1166 const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null };1224 const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null };
1167 const got_index = try self.allocateGotEntry(got_target);1225 const got_index = try self.allocateGotEntry(got_target);
1168 const got_atom = try self.createGotAtom(got_target);1226 const got_atom_index = try self.createGotAtom(got_target);
1227 const got_atom = self.getAtom(got_atom_index);
1169 self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;1228 self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;
1170 try self.writePtrWidthAtom(got_atom);1229 try self.writePtrWidthAtom(got_atom_index);
1171 }1230 }
11721231
1173 self.markRelocsDirtyByTarget(atom.getSymbolWithLoc());1232 self.markRelocsDirtyByTarget(atom.getSymbolWithLoc());
1174 try self.writeAtom(atom, code);1233 try self.writeAtom(atom_index, code);
1175}
1176
1177fn freeRelocationsForAtom(self: *Coff, atom: *Atom) void {
1178 var removed_relocs = self.relocs.fetchRemove(atom);
1179 if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator);
1180 var removed_base_relocs = self.base_relocs.fetchRemove(atom);
1181 if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(self.base.allocator);
1182}1234}
11831235
1184fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void {1236fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void {
1185 const gpa = self.base.allocator;1237 const gpa = self.base.allocator;
1186 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;1238 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
1187 for (unnamed_consts.items) |atom| {1239 for (unnamed_consts.items) |atom_index| {
1188 self.freeAtom(atom);1240 self.freeAtom(atom_index);
1189 }1241 }
1190 unnamed_consts.clearAndFree(gpa);1242 unnamed_consts.clearAndFree(gpa);
1191}1243}
...@@ -1200,11 +1252,11 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {...@@ -1200,11 +1252,11 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
12001252
1201 log.debug("freeDecl {*}", .{decl});1253 log.debug("freeDecl {*}", .{decl});
12021254
1203 if (self.decls.fetchRemove(decl_index)) |kv| {1255 if (self.decls.fetchRemove(decl_index)) |const_kv| {
1204 if (kv.value) |_| {1256 var kv = const_kv;
1205 self.freeAtom(&decl.link.coff);1257 self.freeAtom(kv.value.atom);
1206 self.freeUnnamedConsts(decl_index);1258 self.freeUnnamedConsts(decl_index);
1207 }1259 kv.value.exports.deinit(self.base.allocator);
1208 }1260 }
1209}1261}
12101262
...@@ -1257,16 +1309,10 @@ pub fn updateDeclExports(...@@ -1257,16 +1309,10 @@ pub fn updateDeclExports(
1257 const gpa = self.base.allocator;1309 const gpa = self.base.allocator;
12581310
1259 const decl = module.declPtr(decl_index);1311 const decl = module.declPtr(decl_index);
1260 const atom = &decl.link.coff;1312 const atom_index = try self.getOrCreateAtomForDecl(decl_index);
12611313 const atom = self.getAtom(atom_index);
1262 if (atom.getSymbolIndex() == null) return;
1263
1264 const gop = try self.decls.getOrPut(gpa, decl_index);
1265 if (!gop.found_existing) {
1266 gop.value_ptr.* = self.getDeclOutputSection(decl);
1267 }
1268
1269 const decl_sym = atom.getSymbol(self);1314 const decl_sym = atom.getSymbol(self);
1315 const decl_metadata = self.decls.getPtr(decl_index).?;
12701316
1271 for (exports) |exp| {1317 for (exports) |exp| {
1272 log.debug("adding new export '{s}'", .{exp.options.name});1318 log.debug("adding new export '{s}'", .{exp.options.name});
...@@ -1301,9 +1347,9 @@ pub fn updateDeclExports(...@@ -1301,9 +1347,9 @@ pub fn updateDeclExports(
1301 continue;1347 continue;
1302 }1348 }
13031349
1304 const sym_index = exp.link.coff.sym_index orelse blk: {1350 const sym_index = decl_metadata.getExport(self, exp.options.name) orelse blk: {
1305 const sym_index = try self.allocateSymbol();1351 const sym_index = try self.allocateSymbol();
1306 exp.link.coff.sym_index = sym_index;1352 try decl_metadata.exports.append(gpa, sym_index);
1307 break :blk sym_index;1353 break :blk sym_index;
1308 };1354 };
1309 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };1355 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
...@@ -1326,16 +1372,15 @@ pub fn updateDeclExports(...@@ -1326,16 +1372,15 @@ pub fn updateDeclExports(
1326 }1372 }
1327}1373}
13281374
1329pub fn deleteExport(self: *Coff, exp: Export) void {1375pub fn deleteDeclExport(self: *Coff, decl_index: Module.Decl.Index, name: []const u8) void {
1330 if (self.llvm_object) |_| return;1376 if (self.llvm_object) |_| return;
1331 const sym_index = exp.sym_index orelse return;1377 const metadata = self.decls.getPtr(decl_index) orelse return;
1378 const sym_index = metadata.getExportPtr(self, name) orelse return;
13321379
1333 const gpa = self.base.allocator;1380 const gpa = self.base.allocator;
13341381 const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null };
1335 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
1336 const sym = self.getSymbolPtr(sym_loc);1382 const sym = self.getSymbolPtr(sym_loc);
1337 const sym_name = self.getSymbolName(sym_loc);1383 log.debug("deleting export '{s}'", .{name});
1338 log.debug("deleting export '{s}'", .{sym_name});
1339 assert(sym.storage_class == .EXTERNAL and sym.section_number != .UNDEFINED);1384 assert(sym.storage_class == .EXTERNAL and sym.section_number != .UNDEFINED);
1340 sym.* = .{1385 sym.* = .{
1341 .name = [_]u8{0} ** 8,1386 .name = [_]u8{0} ** 8,
...@@ -1345,9 +1390,9 @@ pub fn deleteExport(self: *Coff, exp: Export) void {...@@ -1345,9 +1390,9 @@ pub fn deleteExport(self: *Coff, exp: Export) void {
1345 .storage_class = .NULL,1390 .storage_class = .NULL,
1346 .number_of_aux_symbols = 0,1391 .number_of_aux_symbols = 0,
1347 };1392 };
1348 self.locals_free_list.append(gpa, sym_index) catch {};1393 self.locals_free_list.append(gpa, sym_index.*) catch {};
13491394
1350 if (self.resolver.fetchRemove(sym_name)) |entry| {1395 if (self.resolver.fetchRemove(name)) |entry| {
1351 defer gpa.free(entry.key);1396 defer gpa.free(entry.key);
1352 self.globals_free_list.append(gpa, entry.value) catch {};1397 self.globals_free_list.append(gpa, entry.value) catch {};
1353 self.globals.items[entry.value] = .{1398 self.globals.items[entry.value] = .{
...@@ -1355,6 +1400,8 @@ pub fn deleteExport(self: *Coff, exp: Export) void {...@@ -1355,6 +1400,8 @@ pub fn deleteExport(self: *Coff, exp: Export) void {
1355 .file = null,1400 .file = null,
1356 };1401 };
1357 }1402 }
1403
1404 sym_index.* = 0;
1358}1405}
13591406
1360fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void {1407fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void {
...@@ -1419,9 +1466,10 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1419,9 +1466,10 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
1419 if (self.imports_table.contains(global)) continue;1466 if (self.imports_table.contains(global)) continue;
14201467
1421 const import_index = try self.allocateImportEntry(global);1468 const import_index = try self.allocateImportEntry(global);
1422 const import_atom = try self.createImportAtom();1469 const import_atom_index = try self.createImportAtom();
1470 const import_atom = self.getAtom(import_atom_index);
1423 self.imports.items[import_index].sym_index = import_atom.getSymbolIndex().?;1471 self.imports.items[import_index].sym_index = import_atom.getSymbolIndex().?;
1424 try self.writePtrWidthAtom(import_atom);1472 try self.writePtrWidthAtom(import_atom_index);
1425 }1473 }
14261474
1427 if (build_options.enable_logging) {1475 if (build_options.enable_logging) {
...@@ -1455,22 +1503,14 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1455,22 +1503,14 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
1455 }1503 }
1456}1504}
14571505
1458pub fn getDeclVAddr(1506pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 {
1459 self: *Coff,
1460 decl_index: Module.Decl.Index,
1461 reloc_info: link.File.RelocInfo,
1462) !u64 {
1463 const mod = self.base.options.module.?;
1464 const decl = mod.declPtr(decl_index);
1465
1466 assert(self.llvm_object == null);1507 assert(self.llvm_object == null);
14671508
1468 try decl.link.coff.ensureInitialized(self);1509 const this_atom_index = try self.getOrCreateAtomForDecl(decl_index);
1469 const sym_index = decl.link.coff.getSymbolIndex().?;1510 const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?;
14701511 const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
1471 const atom = self.getAtomForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
1472 const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };1512 const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
1473 try atom.addRelocation(self, .{1513 try Atom.addRelocation(self, atom_index, .{
1474 .type = .direct,1514 .type = .direct,
1475 .target = target,1515 .target = target,
1476 .offset = @intCast(u32, reloc_info.offset),1516 .offset = @intCast(u32, reloc_info.offset),
...@@ -1478,7 +1518,7 @@ pub fn getDeclVAddr(...@@ -1478,7 +1518,7 @@ pub fn getDeclVAddr(
1478 .pcrel = false,1518 .pcrel = false,
1479 .length = 3,1519 .length = 3,
1480 });1520 });
1481 try atom.addBaseRelocation(self, @intCast(u32, reloc_info.offset));1521 try Atom.addBaseRelocation(self, atom_index, @intCast(u32, reloc_info.offset));
14821522
1483 return 0;1523 return 0;
1484}1524}
...@@ -1529,7 +1569,8 @@ fn writeBaseRelocations(self: *Coff) !void {...@@ -1529,7 +1569,8 @@ fn writeBaseRelocations(self: *Coff) !void {
15291569
1530 var it = self.base_relocs.iterator();1570 var it = self.base_relocs.iterator();
1531 while (it.next()) |entry| {1571 while (it.next()) |entry| {
1532 const atom = entry.key_ptr.*;1572 const atom_index = entry.key_ptr.*;
1573 const atom = self.getAtom(atom_index);
1533 const offsets = entry.value_ptr.*;1574 const offsets = entry.value_ptr.*;
15341575
1535 for (offsets.items) |offset| {1576 for (offsets.items) |offset| {
...@@ -1613,7 +1654,8 @@ fn writeImportTable(self: *Coff) !void {...@@ -1613,7 +1654,8 @@ fn writeImportTable(self: *Coff) !void {
1613 const gpa = self.base.allocator;1654 const gpa = self.base.allocator;
16141655
1615 const section = self.sections.get(self.idata_section_index.?);1656 const section = self.sections.get(self.idata_section_index.?);
1616 const last_atom = section.last_atom orelse return;1657 const last_atom_index = section.last_atom_index orelse return;
1658 const last_atom = self.getAtom(last_atom_index);
16171659
1618 const iat_rva = section.header.virtual_address;1660 const iat_rva = section.header.virtual_address;
1619 const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer1661 const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer
...@@ -2051,27 +2093,37 @@ pub fn getOrPutGlobalPtr(self: *Coff, name: []const u8) !GetOrPutGlobalPtrResult...@@ -2051,27 +2093,37 @@ pub fn getOrPutGlobalPtr(self: *Coff, name: []const u8) !GetOrPutGlobalPtrResult
2051 return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr };2093 return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr };
2052}2094}
20532095
2096pub fn getAtom(self: *const Coff, atom_index: Atom.Index) Atom {
2097 assert(atom_index < self.atoms.items.len);
2098 return self.atoms.items[atom_index];
2099}
2100
2101pub fn getAtomPtr(self: *Coff, atom_index: Atom.Index) *Atom {
2102 assert(atom_index < self.atoms.items.len);
2103 return &self.atoms.items[atom_index];
2104}
2105
2054/// Returns atom if there is an atom referenced by the symbol described by `sym_loc` descriptor.2106/// Returns atom if there is an atom referenced by the symbol described by `sym_loc` descriptor.
2055/// Returns null on failure.2107/// Returns null on failure.
2056pub fn getAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom {2108pub fn getAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom.Index {
2057 assert(sym_loc.file == null); // TODO linking with object files2109 assert(sym_loc.file == null); // TODO linking with object files
2058 return self.atom_by_index_table.get(sym_loc.sym_index);2110 return self.atom_by_index_table.get(sym_loc.sym_index);
2059}2111}
20602112
2061/// Returns GOT atom that references `sym_loc` if one exists.2113/// Returns GOT atom that references `sym_loc` if one exists.
2062/// Returns null otherwise.2114/// Returns null otherwise.
2063pub fn getGotAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom {2115pub fn getGotAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom.Index {
2064 const got_index = self.got_entries_table.get(sym_loc) orelse return null;2116 const got_index = self.got_entries_table.get(sym_loc) orelse return null;
2065 const got_entry = self.got_entries.items[got_index];2117 const got_entry = self.got_entries.items[got_index];
2066 return self.getAtomForSymbol(.{ .sym_index = got_entry.sym_index, .file = null });2118 return self.getAtomIndexForSymbol(.{ .sym_index = got_entry.sym_index, .file = null });
2067}2119}
20682120
2069/// Returns import atom that references `sym_loc` if one exists.2121/// Returns import atom that references `sym_loc` if one exists.
2070/// Returns null otherwise.2122/// Returns null otherwise.
2071pub fn getImportAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom {2123pub fn getImportAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom.Index {
2072 const imports_index = self.imports_table.get(sym_loc) orelse return null;2124 const imports_index = self.imports_table.get(sym_loc) orelse return null;
2073 const imports_entry = self.imports.items[imports_index];2125 const imports_entry = self.imports.items[imports_index];
2074 return self.getAtomForSymbol(.{ .sym_index = imports_entry.sym_index, .file = null });2126 return self.getAtomIndexForSymbol(.{ .sym_index = imports_entry.sym_index, .file = null });
2075}2127}
20762128
2077fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void {2129fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void {
src/link/Coff/Atom.zig+24-24
...@@ -27,23 +27,10 @@ alignment: u32,...@@ -27,23 +27,10 @@ alignment: u32,
2727
28/// Points to the previous and next neighbors, based on the `text_offset`.28/// Points to the previous and next neighbors, based on the `text_offset`.
29/// This can be used to find, for example, the capacity of this `Atom`.29/// This can be used to find, for example, the capacity of this `Atom`.
30prev: ?*Atom,30prev_index: ?Index,
31next: ?*Atom,31next_index: ?Index,
3232
33pub const empty = Atom{33pub const Index = u32;
34 .sym_index = 0,
35 .file = null,
36 .size = 0,
37 .alignment = 0,
38 .prev = null,
39 .next = null,
40};
41
42pub fn ensureInitialized(self: *Atom, coff_file: *Coff) !void {
43 if (self.getSymbolIndex() != null) return; // Already initialized
44 self.sym_index = try coff_file.allocateSymbol();
45 try coff_file.atom_by_index_table.putNoClobber(coff_file.base.allocator, self.sym_index, self);
46}
4734
48pub fn getSymbolIndex(self: Atom) ?u32 {35pub fn getSymbolIndex(self: Atom) ?u32 {
49 if (self.sym_index == 0) return null;36 if (self.sym_index == 0) return null;
...@@ -85,7 +72,8 @@ pub fn getName(self: Atom, coff_file: *const Coff) []const u8 {...@@ -85,7 +72,8 @@ pub fn getName(self: Atom, coff_file: *const Coff) []const u8 {
85/// Returns how much room there is to grow in virtual address space.72/// Returns how much room there is to grow in virtual address space.
86pub fn capacity(self: Atom, coff_file: *const Coff) u32 {73pub fn capacity(self: Atom, coff_file: *const Coff) u32 {
87 const self_sym = self.getSymbol(coff_file);74 const self_sym = self.getSymbol(coff_file);
88 if (self.next) |next| {75 if (self.next_index) |next_index| {
76 const next = coff_file.getAtom(next_index);
89 const next_sym = next.getSymbol(coff_file);77 const next_sym = next.getSymbol(coff_file);
90 return next_sym.value - self_sym.value;78 return next_sym.value - self_sym.value;
91 } else {79 } else {
...@@ -97,7 +85,8 @@ pub fn capacity(self: Atom, coff_file: *const Coff) u32 {...@@ -97,7 +85,8 @@ pub fn capacity(self: Atom, coff_file: *const Coff) u32 {
9785
98pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool {86pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool {
99 // No need to keep a free list node for the last atom.87 // No need to keep a free list node for the last atom.
100 const next = self.next orelse return false;88 const next_index = self.next_index orelse return false;
89 const next = coff_file.getAtom(next_index);
101 const self_sym = self.getSymbol(coff_file);90 const self_sym = self.getSymbol(coff_file);
102 const next_sym = next.getSymbol(coff_file);91 const next_sym = next.getSymbol(coff_file);
103 const cap = next_sym.value - self_sym.value;92 const cap = next_sym.value - self_sym.value;
...@@ -107,22 +96,33 @@ pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool {...@@ -107,22 +96,33 @@ pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool {
107 return surplus >= Coff.min_text_capacity;96 return surplus >= Coff.min_text_capacity;
108}97}
10998
110pub fn addRelocation(self: *Atom, coff_file: *Coff, reloc: Relocation) !void {99pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !void {
111 const gpa = coff_file.base.allocator;100 const gpa = coff_file.base.allocator;
112 log.debug(" (adding reloc of type {s} to target %{d})", .{ @tagName(reloc.type), reloc.target.sym_index });101 log.debug(" (adding reloc of type {s} to target %{d})", .{ @tagName(reloc.type), reloc.target.sym_index });
113 const gop = try coff_file.relocs.getOrPut(gpa, self);102 const gop = try coff_file.relocs.getOrPut(gpa, atom_index);
114 if (!gop.found_existing) {103 if (!gop.found_existing) {
115 gop.value_ptr.* = .{};104 gop.value_ptr.* = .{};
116 }105 }
117 try gop.value_ptr.append(gpa, reloc);106 try gop.value_ptr.append(gpa, reloc);
118}107}
119108
120pub fn addBaseRelocation(self: *Atom, coff_file: *Coff, offset: u32) !void {109pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void {
121 const gpa = coff_file.base.allocator;110 const gpa = coff_file.base.allocator;
122 log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{ offset, self.sym_index });111 log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{
123 const gop = try coff_file.base_relocs.getOrPut(gpa, self);112 offset,
113 coff_file.getAtom(atom_index).getSymbolIndex().?,
114 });
115 const gop = try coff_file.base_relocs.getOrPut(gpa, atom_index);
124 if (!gop.found_existing) {116 if (!gop.found_existing) {
125 gop.value_ptr.* = .{};117 gop.value_ptr.* = .{};
126 }118 }
127 try gop.value_ptr.append(gpa, offset);119 try gop.value_ptr.append(gpa, offset);
128}120}
121
122pub fn freeRelocations(coff_file: *Coff, atom_index: Atom.Index) void {
123 const gpa = coff_file.base.allocator;
124 var removed_relocs = coff_file.relocs.fetchRemove(atom_index);
125 if (removed_relocs) |*relocs| relocs.value.deinit(gpa);
126 var removed_base_relocs = coff_file.base_relocs.fetchRemove(atom_index);
127 if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(gpa);
128}
src/link/Coff/Relocation.zig+10-8
...@@ -46,33 +46,35 @@ length: u2,...@@ -46,33 +46,35 @@ length: u2,
46dirty: bool = true,46dirty: bool = true,
4747
48/// Returns an Atom which is the target node of this relocation edge (if any).48/// Returns an Atom which is the target node of this relocation edge (if any).
49pub fn getTargetAtom(self: Relocation, coff_file: *Coff) ?*Atom {49pub fn getTargetAtomIndex(self: Relocation, coff_file: *const Coff) ?Atom.Index {
50 switch (self.type) {50 switch (self.type) {
51 .got,51 .got,
52 .got_page,52 .got_page,
53 .got_pageoff,53 .got_pageoff,
54 => return coff_file.getGotAtomForSymbol(self.target),54 => return coff_file.getGotAtomIndexForSymbol(self.target),
5555
56 .direct,56 .direct,
57 .page,57 .page,
58 .pageoff,58 .pageoff,
59 => return coff_file.getAtomForSymbol(self.target),59 => return coff_file.getAtomIndexForSymbol(self.target),
6060
61 .import,61 .import,
62 .import_page,62 .import_page,
63 .import_pageoff,63 .import_pageoff,
64 => return coff_file.getImportAtomForSymbol(self.target),64 => return coff_file.getImportAtomIndexForSymbol(self.target),
65 }65 }
66}66}
6767
68pub fn resolve(self: *Relocation, atom: *Atom, coff_file: *Coff) !void {68pub fn resolve(self: *Relocation, atom_index: Atom.Index, coff_file: *Coff) !void {
69 const atom = coff_file.getAtom(atom_index);
69 const source_sym = atom.getSymbol(coff_file);70 const source_sym = atom.getSymbol(coff_file);
70 const source_section = coff_file.sections.get(@enumToInt(source_sym.section_number) - 1).header;71 const source_section = coff_file.sections.get(@enumToInt(source_sym.section_number) - 1).header;
71 const source_vaddr = source_sym.value + self.offset;72 const source_vaddr = source_sym.value + self.offset;
7273
73 const file_offset = source_section.pointer_to_raw_data + source_sym.value - source_section.virtual_address;74 const file_offset = source_section.pointer_to_raw_data + source_sym.value - source_section.virtual_address;
7475
75 const target_atom = self.getTargetAtom(coff_file) orelse return;76 const target_atom_index = self.getTargetAtomIndex(coff_file) orelse return;
77 const target_atom = coff_file.getAtom(target_atom_index);
76 const target_vaddr = target_atom.getSymbol(coff_file).value;78 const target_vaddr = target_atom.getSymbol(coff_file).value;
77 const target_vaddr_with_addend = target_vaddr + self.addend;79 const target_vaddr_with_addend = target_vaddr + self.addend;
7880
...@@ -107,7 +109,7 @@ const Context = struct {...@@ -107,7 +109,7 @@ const Context = struct {
107 image_base: u64,109 image_base: u64,
108};110};
109111
110fn resolveAarch64(self: *Relocation, ctx: Context, coff_file: *Coff) !void {112fn resolveAarch64(self: Relocation, ctx: Context, coff_file: *Coff) !void {
111 var buffer: [@sizeOf(u64)]u8 = undefined;113 var buffer: [@sizeOf(u64)]u8 = undefined;
112 switch (self.length) {114 switch (self.length) {
113 2 => {115 2 => {
...@@ -197,7 +199,7 @@ fn resolveAarch64(self: *Relocation, ctx: Context, coff_file: *Coff) !void {...@@ -197,7 +199,7 @@ fn resolveAarch64(self: *Relocation, ctx: Context, coff_file: *Coff) !void {
197 }199 }
198}200}
199201
200fn resolveX86(self: *Relocation, ctx: Context, coff_file: *Coff) !void {202fn resolveX86(self: Relocation, ctx: Context, coff_file: *Coff) !void {
201 switch (self.type) {203 switch (self.type) {
202 .got_page => unreachable,204 .got_page => unreachable,
203 .got_pageoff => unreachable,205 .got_pageoff => unreachable,
src/link/Elf.zig+8-2
...@@ -71,14 +71,14 @@ const DeclMetadata = struct {...@@ -71,14 +71,14 @@ const DeclMetadata = struct {
7171
72 fn getExport(m: DeclMetadata, elf_file: *const Elf, name: []const u8) ?u32 {72 fn getExport(m: DeclMetadata, elf_file: *const Elf, name: []const u8) ?u32 {
73 for (m.exports.items) |exp| {73 for (m.exports.items) |exp| {
74 if (mem.eql(u8, name, elf_file.getSymbolName(exp))) return exp;74 if (mem.eql(u8, name, elf_file.getGlobalName(exp))) return exp;
75 }75 }
76 return null;76 return null;
77 }77 }
7878
79 fn getExportPtr(m: *DeclMetadata, elf_file: *Elf, name: []const u8) ?*u32 {79 fn getExportPtr(m: *DeclMetadata, elf_file: *Elf, name: []const u8) ?*u32 {
80 for (m.exports.items) |*exp| {80 for (m.exports.items) |*exp| {
81 if (mem.eql(u8, name, elf_file.getSymbolName(exp.*))) return exp;81 if (mem.eql(u8, name, elf_file.getGlobalName(exp.*))) return exp;
82 }82 }
83 return null;83 return null;
84 }84 }
...@@ -3276,6 +3276,12 @@ pub fn getSymbolName(self: *const Elf, sym_index: u32) []const u8 {...@@ -3276,6 +3276,12 @@ pub fn getSymbolName(self: *const Elf, sym_index: u32) []const u8 {
3276 return self.shstrtab.get(sym.st_name).?;3276 return self.shstrtab.get(sym.st_name).?;
3277}3277}
32783278
3279/// Returns name of the global symbol at index.
3280pub fn getGlobalName(self: *const Elf, index: u32) []const u8 {
3281 const sym = self.global_symbols.items[index];
3282 return self.shstrtab.get(sym.st_name).?;
3283}
3284
3279pub fn getAtom(self: *const Elf, atom_index: Atom.Index) Atom {3285pub fn getAtom(self: *const Elf, atom_index: Atom.Index) Atom {
3280 assert(atom_index < self.atoms.items.len);3286 assert(atom_index < self.atoms.items.len);
3281 return self.atoms.items[atom_index];3287 return self.atoms.items[atom_index];
src/link/MachO.zig+5
...@@ -3015,6 +3015,11 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm...@@ -3015,6 +3015,11 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm
3015 if (header.@"align" < align_pow) {3015 if (header.@"align" < align_pow) {
3016 header.@"align" = align_pow;3016 header.@"align" = align_pow;
3017 }3017 }
3018 {
3019 const atom_ptr = self.getAtomPtr(atom_index);
3020 atom_ptr.size = new_atom_size;
3021 atom_ptr.alignment = @intCast(u32, alignment);
3022 }
30183023
3019 if (atom.prev_index) |prev_index| {3024 if (atom.prev_index) |prev_index| {
3020 const prev = self.getAtomPtr(prev_index);3025 const prev = self.getAtomPtr(prev_index);