| ... | ... | @@ -2663,11 +2663,28 @@ fn getOrPutGlobalSymbol( |
| 2663 | 2663 | coff: *Coff, |
| 2664 | 2664 | opts: GlobalOptions, |
| 2665 | 2665 | ) !std.AutoArrayHashMapUnmanaged(GlobalName, Symbol.Index).GetOrPutResult { |
| 2666 | | const gpa = coff.base.comp.gpa; |
| 2666 | const comp = coff.base.comp; |
| 2667 | const gpa = comp.gpa; |
| 2667 | 2668 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 2669 | |
| 2670 | const lib_name = if (opts.lib_name) |lib_name| lib_name: { |
| 2671 | const is_libc = std.zig.target.isLibCLibName(&comp.root_mod.resolved_target.result, lib_name); |
| 2672 | if (is_libc) { |
| 2673 | // This is guaranteed by Sema.handleExternLibName |
| 2674 | if (!comp.config.link_libc) unreachable; |
| 2675 | |
| 2676 | // TODO: The user has requested this symbol come from libc, but this logic allows |
| 2677 | // it to come from anywhere. We need to know what inputs are libc inputs, |
| 2678 | // and set a flag to only search them for this symbol. |
| 2679 | break :lib_name null; |
| 2680 | } |
| 2681 | |
| 2682 | break :lib_name lib_name; |
| 2683 | } else null; |
| 2684 | |
| 2668 | 2685 | const sym_gop = try coff.globals.getOrPut(gpa, .{ |
| 2669 | 2686 | .name = try coff.getOrPutString(opts.name), |
| 2670 | | .lib_name = try coff.getOrPutOptionalString(opts.lib_name), |
| 2687 | .lib_name = try coff.getOrPutOptionalString(lib_name), |
| 2671 | 2688 | }); |
| 2672 | 2689 | if (!sym_gop.found_existing) { |
| 2673 | 2690 | const si = coff.addSymbolAssumeCapacity(); |
| ... | ... | @@ -5576,6 +5593,7 @@ pub fn flush( |
| 5576 | 5593 | // this should be set after updateExports instead |
| 5577 | 5594 | coff.exports_complete = true; |
| 5578 | 5595 | |
| 5596 | while (try coff.resolve(tid)) {} |
| 5579 | 5597 | while (try coff.idle(tid)) {} |
| 5580 | 5598 | |
| 5581 | 5599 | if (coff.isImage()) |
| ... | ... | @@ -5598,7 +5616,10 @@ pub fn flush( |
| 5598 | 5616 | return comp.link_diags.fail("dumping link snapshot failed: {t}", .{err}); |
| 5599 | 5617 | } |
| 5600 | 5618 | |
| 5601 | | pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5619 | /// Runs a single "resolution" task. |
| 5620 | /// These are tasks that need to modify the node structure in some way. |
| 5621 | /// They must run in a defined order with respect to linker tasks. |
| 5622 | fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5602 | 5623 | const comp = coff.base.comp; |
| 5603 | 5624 | task: { |
| 5604 | 5625 | while (coff.section_merge_pending_index < coff.section_merges.count()) { |
| ... | ... | @@ -5658,7 +5679,7 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5658 | 5679 | }; |
| 5659 | 5680 | break :task; |
| 5660 | 5681 | } |
| 5661 | | if (coff.inputs_complete and coff.global_pending_index < coff.globals.count()) { |
| 5682 | if (coff.exports_complete and coff.global_pending_index < coff.globals.count()) { |
| 5662 | 5683 | const gmi: Node.GlobalMapIndex = .wrap(coff.global_pending_index); |
| 5663 | 5684 | const sub_prog_node = coff.synth_prog_node.start( |
| 5664 | 5685 | gmi.globalName(coff).name.toSlice(coff), |
| ... | ... | @@ -5751,6 +5772,53 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5751 | 5772 | }; |
| 5752 | 5773 | break :task; |
| 5753 | 5774 | } |
| 5775 | if (coff.symbol_table.pending_shrink) { |
| 5776 | defer coff.symbol_table.pending_shrink = false; |
| 5777 | const sub_prog_node = coff.idleProgNode( |
| 5778 | tid, |
| 5779 | coff.symbol_prog_node, |
| 5780 | coff.getNode(coff.symbol_table.ni), |
| 5781 | ); |
| 5782 | defer sub_prog_node.end(); |
| 5783 | |
| 5784 | const number_of_symbols = coff.targetLoad(&coff.headerPtr().number_of_symbols); |
| 5785 | coff.symbol_table.ni.shrink( |
| 5786 | &coff.mf, |
| 5787 | comp.gpa, |
| 5788 | number_of_symbols * std.coff.Symbol.sizeOf(), |
| 5789 | true, |
| 5790 | ) catch |err| switch (err) { |
| 5791 | error.OutOfMemory => return error.OutOfMemory, |
| 5792 | else => |e| return comp.link_diags.fail( |
| 5793 | "linker failed to compact symbol table: {t}", |
| 5794 | .{e}, |
| 5795 | ), |
| 5796 | }; |
| 5797 | |
| 5798 | break :task; |
| 5799 | } |
| 5800 | } |
| 5801 | |
| 5802 | if (coff.section_merge_pending_index < coff.section_merges.count()) return true; |
| 5803 | if (coff.pending_uavs.count() > 0) return true; |
| 5804 | if (coff.pending_input != null) return true; |
| 5805 | if (coff.exports_complete and coff.globals.count() > coff.global_pending_index) return true; |
| 5806 | assert(!coff.exports_complete or coff.inputs_complete); |
| 5807 | if (coff.exports_complete and coff.late_globals.items.len > coff.late_globals_pending_index) return true; |
| 5808 | if (coff.exports_complete and coff.pending_special_symbol != .none) return true; |
| 5809 | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; |
| 5810 | if (coff.symbol_table.pending.count() > 0) return true; |
| 5811 | if (coff.symbol_table.pending_shrink) return true; |
| 5812 | return false; |
| 5813 | } |
| 5814 | |
| 5815 | pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5816 | // Idle tasks should not modify create / modify nodes, otherwise the output is not reproducible. |
| 5817 | coff.mf.nodes_lock.lock(); |
| 5818 | defer coff.mf.nodes_lock.unlock(); |
| 5819 | |
| 5820 | const comp = coff.base.comp; |
| 5821 | task: { |
| 5754 | 5822 | // TODO: Idle task for flushing obj into lib |
| 5755 | 5823 | if (coff.input_section_pending_index < coff.input_sections.items.len) { |
| 5756 | 5824 | const isi: Node.InputSection.Index = @enumFromInt(coff.input_section_pending_index); |
| ... | ... | @@ -5809,46 +5877,11 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5809 | 5877 | coff.flushExportsSort(); |
| 5810 | 5878 | break :task; |
| 5811 | 5879 | } |
| 5812 | | if (coff.symbol_table.pending_shrink) { |
| 5813 | | defer coff.symbol_table.pending_shrink = false; |
| 5814 | | const sub_prog_node = coff.idleProgNode( |
| 5815 | | tid, |
| 5816 | | coff.symbol_prog_node, |
| 5817 | | coff.getNode(coff.symbol_table.ni), |
| 5818 | | ); |
| 5819 | | defer sub_prog_node.end(); |
| 5820 | | |
| 5821 | | const number_of_symbols = coff.targetLoad(&coff.headerPtr().number_of_symbols); |
| 5822 | | coff.symbol_table.ni.shrink( |
| 5823 | | &coff.mf, |
| 5824 | | comp.gpa, |
| 5825 | | number_of_symbols * std.coff.Symbol.sizeOf(), |
| 5826 | | true, |
| 5827 | | ) catch |err| switch (err) { |
| 5828 | | error.OutOfMemory => return error.OutOfMemory, |
| 5829 | | else => |e| return comp.link_diags.fail( |
| 5830 | | "linker failed to compact symbol table: {t}", |
| 5831 | | .{e}, |
| 5832 | | ), |
| 5833 | | }; |
| 5834 | | |
| 5835 | | break :task; |
| 5836 | | } |
| 5837 | 5880 | } |
| 5838 | | if (coff.section_merge_pending_index < coff.section_merges.count()) return true; |
| 5839 | | if (coff.pending_uavs.count() > 0) return true; |
| 5840 | | if (coff.pending_input != null) return true; |
| 5841 | | if (coff.inputs_complete and coff.globals.count() > coff.global_pending_index) return true; |
| 5842 | | assert(!coff.exports_complete or coff.inputs_complete); |
| 5843 | | if (coff.exports_complete and coff.late_globals.items.len > coff.late_globals_pending_index) return true; |
| 5844 | | if (coff.exports_complete and coff.pending_special_symbol != .none) return true; |
| 5845 | | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; |
| 5846 | | if (coff.symbol_table.pending.count() > 0) return true; |
| 5847 | 5881 | if (coff.input_sections.items.len > coff.input_section_pending_index) return true; |
| 5848 | 5882 | if (coff.mf.updates.items.len > 0) return true; |
| 5849 | 5883 | if (coff.pending_members.count() > 0) return true; |
| 5850 | 5884 | if (coff.export_table.pending_sort) return true; |
| 5851 | | if (coff.symbol_table.pending_shrink) return true; |
| 5852 | 5885 | return false; |
| 5853 | 5886 | } |
| 5854 | 5887 | |
| ... | ... | @@ -6924,7 +6957,6 @@ fn flushMember(coff: *Coff, mi: Member.Index) !void { |
| 6924 | 6957 | }); |
| 6925 | 6958 | |
| 6926 | 6959 | var offset: u64 = 0; |
| 6927 | | |
| 6928 | 6960 | var string_table = coff.secondLinkerMemberStringsSlice(); |
| 6929 | 6961 | for (coff.lib_string_table.items) |string| { |
| 6930 | 6962 | const str = string.toSlice(coff); |
| ... | ... | @@ -7096,6 +7128,7 @@ fn updateExportsInner( |
| 7096 | 7128 | Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu), |
| 7097 | 7129 | ))), |
| 7098 | 7130 | }; |
| 7131 | while (try coff.resolve(pt.tid)) {} |
| 7099 | 7132 | while (try coff.idle(pt.tid)) {} |
| 7100 | 7133 | |
| 7101 | 7134 | const machine = coff.targetLoad(&coff.headerPtr().machine); |