| ... | @@ -615,7 +615,8 @@ pub const SymbolTable = struct { | ... | @@ -615,7 +615,8 @@ pub const SymbolTable = struct { |
| 615 | ni: MappedFile.Node.Index, | 615 | ni: MappedFile.Node.Index, |
| 616 | strings_ni: MappedFile.Node.Index, | 616 | strings_ni: MappedFile.Node.Index, |
| 617 | strings: std.AutoArrayHashMapUnmanaged(String, StringIndex), | 617 | strings: std.AutoArrayHashMapUnmanaged(String, StringIndex), |
| 618 | pending: std.AutoArrayHashMapUnmanaged(Symbol.Index, void), | 618 | symbols: std.AutoArrayHashMapUnmanaged(Symbol.Index, SymbolTable.Index), |
| | 619 | pending_symbol_index: u32, |
| 619 | | 620 | |
| 620 | // Resizing the symbol table node has the result of accumulating padding | 621 | // Resizing the symbol table node has the result of accumulating padding |
| 621 | // between the last symbol in the symbol table node and the start of the | 622 | // between the last symbol in the symbol table node and the start of the |
| ... | @@ -653,8 +654,8 @@ pub const SymbolTable = struct { | ... | @@ -653,8 +654,8 @@ pub const SymbolTable = struct { |
| 653 | none, | 654 | none, |
| 654 | _, | 655 | _, |
| 655 | | 656 | |
| 656 | pub fn wrap(i: ?u32) Index { | 657 | pub fn wrap(i: u32) Index { |
| 657 | return @enumFromInt((i orelse return .none) + 1); | 658 | return @enumFromInt(i + 1); |
| 658 | } | 659 | } |
| 659 | | 660 | |
| 660 | pub fn unwrap(sti: Index) ?u32 { | 661 | pub fn unwrap(sti: Index) ?u32 { |
| ... | @@ -904,13 +905,14 @@ pub const Symbol = struct { | ... | @@ -904,13 +905,14 @@ pub const Symbol = struct { |
| 904 | }; | 905 | }; |
| 905 | | 906 | |
| 906 | const ValueTag = enum(u2) { | 907 | const ValueTag = enum(u2) { |
| | 908 | none, |
| 907 | node_offset, | 909 | node_offset, |
| 908 | weak_alias_si, | 910 | weak_alias_si, |
| 909 | weak_alias_name, | 911 | weak_alias_name, |
| 910 | sti, | | |
| 911 | }; | 912 | }; |
| 912 | | 913 | |
| 913 | pub const Value = union(ValueTag) { | 914 | pub const Value = union(ValueTag) { |
| | 915 | none, |
| 914 | /// The offset of the symbol within its node. Used with symbols that | 916 | /// The offset of the symbol within its node. Used with symbols that |
| 915 | /// don't create their own nodes: .input_section, .import_address_table | 917 | /// don't create their own nodes: .input_section, .import_address_table |
| 916 | /// Images only. | 918 | /// Images only. |
| ... | @@ -924,9 +926,6 @@ pub const Symbol = struct { | ... | @@ -924,9 +926,6 @@ pub const Symbol = struct { |
| 924 | /// be generated and resolved if this symbol is not resolved. | 926 | /// be generated and resolved if this symbol is not resolved. |
| 925 | /// Globals only, images only. | 927 | /// Globals only, images only. |
| 926 | weak_alias_name: String, | 928 | weak_alias_name: String, |
| 927 | /// Index of this symbol in the symbol table | | |
| 928 | /// Only used when outputting objects | | |
| 929 | sti: SymbolTable.Index, | | |
| 930 | }; | 929 | }; |
| 931 | | 930 | |
| 932 | const ExtraTag = enum(u2) { | 931 | const ExtraTag = enum(u2) { |
| ... | @@ -1041,6 +1040,11 @@ pub const Symbol = struct { | ... | @@ -1041,6 +1040,11 @@ pub const Symbol = struct { |
| 1041 | return ni; | 1040 | return ni; |
| 1042 | } | 1041 | } |
| 1043 | | 1042 | |
| | 1043 | pub fn sti(si: Symbol.Index, coff: *Coff) SymbolTable.Index { |
| | 1044 | assert(!coff.isImage()); |
| | 1045 | return coff.symbol_table.symbols.get(si) orelse .none; |
| | 1046 | } |
| | 1047 | |
| 1044 | pub fn next(si: Symbol.Index) Symbol.Index { | 1048 | pub fn next(si: Symbol.Index) Symbol.Index { |
| 1045 | return @enumFromInt(@intFromEnum(si) + 1); | 1049 | return @enumFromInt(@intFromEnum(si) + 1); |
| 1046 | } | 1050 | } |
| ... | @@ -1070,7 +1074,7 @@ pub const Symbol = struct { | ... | @@ -1070,7 +1074,7 @@ pub const Symbol = struct { |
| 1070 | | 1074 | |
| 1071 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { | 1075 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { |
| 1072 | const sym = si.get(coff); | 1076 | const sym = si.get(coff); |
| 1073 | const index = sym.value.sti.unwrap() orelse return; | 1077 | const index = si.sti(coff).unwrap().?; |
| 1074 | var ri = sym.target_relocs; | 1078 | var ri = sym.target_relocs; |
| 1075 | while (ri != .none) { | 1079 | while (ri != .none) { |
| 1076 | const reloc = ri.get(coff); | 1080 | const reloc = ri.get(coff); |
| ... | @@ -1583,7 +1587,8 @@ fn create( | ... | @@ -1583,7 +1587,8 @@ fn create( |
| 1583 | .ni = .none, | 1587 | .ni = .none, |
| 1584 | .strings_ni = .none, | 1588 | .strings_ni = .none, |
| 1585 | .strings = .empty, | 1589 | .strings = .empty, |
| 1586 | .pending = .empty, | 1590 | .symbols = .empty, |
| | 1591 | .pending_symbol_index = 0, |
| 1587 | .pending_shrink = false, | 1592 | .pending_shrink = false, |
| 1588 | }, | 1593 | }, |
| 1589 | .inputs = .empty, | 1594 | .inputs = .empty, |
| ... | @@ -1667,7 +1672,7 @@ pub fn deinit(coff: *Coff) void { | ... | @@ -1667,7 +1672,7 @@ pub fn deinit(coff: *Coff) void { |
| 1667 | coff.import_table.iat_symbol_indices.deinit(gpa); | 1672 | coff.import_table.iat_symbol_indices.deinit(gpa); |
| 1668 | coff.export_table.entries.deinit(gpa); | 1673 | coff.export_table.entries.deinit(gpa); |
| 1669 | coff.symbol_table.strings.deinit(gpa); | 1674 | coff.symbol_table.strings.deinit(gpa); |
| 1670 | coff.symbol_table.pending.deinit(gpa); | 1675 | coff.symbol_table.symbols.deinit(gpa); |
| 1671 | coff.inputs.deinit(gpa); | 1676 | coff.inputs.deinit(gpa); |
| 1672 | coff.input_archives.deinit(gpa); | 1677 | coff.input_archives.deinit(gpa); |
| 1673 | coff.input_archive_members.deinit(gpa); | 1678 | coff.input_archive_members.deinit(gpa); |
| ... | @@ -2280,7 +2285,10 @@ pub fn startProgress(coff: *Coff, prog_node: std.Progress.Node) void { | ... | @@ -2280,7 +2285,10 @@ pub fn startProgress(coff: *Coff, prog_node: std.Progress.Node) void { |
| 2280 | }); | 2285 | }); |
| 2281 | if (!isImage(coff)) { | 2286 | if (!isImage(coff)) { |
| 2282 | prog_node.increaseEstimatedTotalItems(2); | 2287 | prog_node.increaseEstimatedTotalItems(2); |
| 2283 | coff.symbol_prog_node = prog_node.start("Symbols", coff.symbol_table.pending.count()); | 2288 | coff.symbol_prog_node = prog_node.start( |
| | 2289 | "Symbols", |
| | 2290 | coff.symbol_table.symbols.count() - coff.symbol_table.pending_symbol_index, |
| | 2291 | ); |
| 2284 | coff.member_prog_node = prog_node.start("Members", coff.pending_members.count()); | 2292 | coff.member_prog_node = prog_node.start("Members", coff.pending_members.count()); |
| 2285 | } | 2293 | } |
| 2286 | coff.input_prog_node = prog_node.start( | 2294 | coff.input_prog_node = prog_node.start( |
| ... | @@ -2550,8 +2558,7 @@ pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.c | ... | @@ -2550,8 +2558,7 @@ pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.c |
| 2550 | return null; | 2558 | return null; |
| 2551 | } | 2559 | } |
| 2552 | | 2560 | |
| 2553 | pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) ?*align(2) std.coff.SectionDefinition { | 2561 | pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.coff.SectionDefinition { |
| 2554 | const sti = si.get(coff).value.sti; | | |
| 2555 | if (symbolTableEntryPtr(coff, sti)) |entry| { | 2562 | if (symbolTableEntryPtr(coff, sti)) |entry| { |
| 2556 | assert(entry.storage_class == .STATIC and entry.number_of_aux_symbols == 1); | 2563 | assert(entry.storage_class == .STATIC and entry.number_of_aux_symbols == 1); |
| 2557 | return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1))); | 2564 | return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1))); |
| ... | @@ -2560,8 +2567,7 @@ pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) ?*align(2) s | ... | @@ -2560,8 +2567,7 @@ pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) ?*align(2) s |
| 2560 | } | 2567 | } |
| 2561 | } | 2568 | } |
| 2562 | | 2569 | |
| 2563 | pub fn symbolTableWeakExternalAuxEntryPtr(coff: *Coff, si: Symbol.Index) ?*align(2) std.coff.WeakExternalDefinition { | 2570 | pub fn symbolTableWeakExternalAuxEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.coff.WeakExternalDefinition { |
| 2564 | const sti = si.get(coff).value.sti; | | |
| 2565 | if (symbolTableEntryPtr(coff, sti)) |entry| { | 2571 | if (symbolTableEntryPtr(coff, sti)) |entry| { |
| 2566 | assert(entry.storage_class == .WEAK_EXTERNAL and entry.number_of_aux_symbols == 1); | 2572 | assert(entry.storage_class == .WEAK_EXTERNAL and entry.number_of_aux_symbols == 1); |
| 2567 | return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1))); | 2573 | return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1))); |
| ... | @@ -2604,10 +2610,10 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { | ... | @@ -2604,10 +2610,10 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2604 | defer coff.symbols.addOneAssumeCapacity().* = .{ | 2610 | defer coff.symbols.addOneAssumeCapacity().* = .{ |
| 2605 | .ni = .none, | 2611 | .ni = .none, |
| 2606 | .rva = 0, | 2612 | .rva = 0, |
| 2607 | .value = .{ .sti = .none }, | 2613 | .value = .{ .none = {} }, |
| 2608 | .extra = .{ .size = 0 }, | 2614 | .extra = .{ .size = 0 }, |
| 2609 | .flags = .{ | 2615 | .flags = .{ |
| 2610 | .value_tag = .sti, | 2616 | .value_tag = .none, |
| 2611 | .extra_tag = .size, | 2617 | .extra_tag = .size, |
| 2612 | .type = .unknown, | 2618 | .type = .unknown, |
| 2613 | .dll_storage_class = .default, | 2619 | .dll_storage_class = .default, |
| ... | @@ -2761,14 +2767,14 @@ pub fn globalSymbol(coff: *Coff, opts: GlobalOptions) !Symbol.Index { | ... | @@ -2761,14 +2767,14 @@ pub fn globalSymbol(coff: *Coff, opts: GlobalOptions) !Symbol.Index { |
| 2761 | pub fn pendingSymbolTableEntry(coff: *Coff, si: Symbol.Index) !void { | 2767 | pub fn pendingSymbolTableEntry(coff: *Coff, si: Symbol.Index) !void { |
| 2762 | assert(!coff.isImage()); | 2768 | assert(!coff.isImage()); |
| 2763 | const sym = si.get(coff); | 2769 | const sym = si.get(coff); |
| 2764 | if (sym.flags.value_tag == .sti and sym.value.sti != .none) | | |
| 2765 | return; | | |
| 2766 | | 2770 | |
| 2767 | assert(sym.ni != .none or sym.gmi != .none); | 2771 | assert(sym.ni != .none or sym.gmi != .none); |
| 2768 | const gpa = coff.base.comp.gpa; | 2772 | const gpa = coff.base.comp.gpa; |
| 2769 | const pending_gop = try coff.symbol_table.pending.getOrPut(gpa, si); | 2773 | const gop = try coff.symbol_table.symbols.getOrPut(gpa, si); |
| 2770 | if (!pending_gop.found_existing) | 2774 | if (!gop.found_existing) { |
| 2771 | coff.symbol_prog_node.increaseEstimatedTotalItems(1); | 2775 | coff.symbol_prog_node.increaseEstimatedTotalItems(1); |
| | 2776 | gop.value_ptr.* = .none; |
| | 2777 | } |
| 2772 | } | 2778 | } |
| 2773 | | 2779 | |
| 2774 | fn navSection( | 2780 | fn navSection( |
| ... | @@ -3047,19 +3053,17 @@ fn ensureMemberSymbol(coff: *Coff, mi: Member.Index, name: String) !void { | ... | @@ -3047,19 +3053,17 @@ fn ensureMemberSymbol(coff: *Coff, mi: Member.Index, name: String) !void { |
| 3047 | coff.member_prog_node.increaseEstimatedTotalItems(1); | 3053 | coff.member_prog_node.increaseEstimatedTotalItems(1); |
| 3048 | } | 3054 | } |
| 3049 | | 3055 | |
| 3050 | fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void { | 3056 | fn flushSymbolTableEntry(coff: *Coff, index: u32, pt: Zcu.PerThread) !void { |
| 3051 | assert(!coff.isImage()); | 3057 | assert(!coff.isImage()); |
| 3052 | const gpa = coff.base.comp.gpa; | 3058 | const gpa = coff.base.comp.gpa; |
| 3053 | | 3059 | |
| | 3060 | const si = coff.symbol_table.symbols.keys()[index]; |
| | 3061 | const sti = &coff.symbol_table.symbols.values()[index]; |
| | 3062 | |
| 3054 | const sym = si.get(coff); | 3063 | const sym = si.get(coff); |
| 3055 | assert(sym.ni != .none or sym.gmi != .none); | 3064 | assert(sym.ni != .none or sym.gmi != .none); |
| 3056 | const existing_sti = switch (sym.flags.value_tag) { | | |
| 3057 | .sti => sym.value.sti, | | |
| 3058 | .weak_alias_si => .none, | | |
| 3059 | else => unreachable, | | |
| 3060 | }; | | |
| 3061 | | 3065 | |
| 3062 | const entry = coff.symbolTableEntryPtr(existing_sti) orelse entry: { | 3066 | const entry = coff.symbolTableEntryPtr(sti.*) orelse entry: { |
| 3063 | var buf: [15]u8 = undefined; | 3067 | var buf: [15]u8 = undefined; |
| 3064 | const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType = | 3068 | const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType = |
| 3065 | if (sym.gmi != .none) blk: { | 3069 | if (sym.gmi != .none) blk: { |
| ... | @@ -3124,11 +3128,10 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void | ... | @@ -3124,11 +3128,10 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3124 | | 3128 | |
| 3125 | try coff.symbol_table.ni.resize(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf()); | 3129 | try coff.symbol_table.ni.resize(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf()); |
| 3126 | | 3130 | |
| 3127 | const old_value = sym.value; | 3131 | sti.* = .wrap(old_num_symbols); |
| 3128 | sym.setValue(.{ .sti = .wrap(old_num_symbols) }); | | |
| 3129 | si.flushSymbolTableIndex(coff); | 3132 | si.flushSymbolTableIndex(coff); |
| 3130 | | 3133 | |
| 3131 | const entry = coff.symbolTableEntryPtr(sym.value.sti).?; | 3134 | const entry = coff.symbolTableEntryPtr(sti.*).?; |
| 3132 | symbol_name.store(coff, &entry.name); | 3135 | symbol_name.store(coff, &entry.name); |
| 3133 | | 3136 | |
| 3134 | entry.section_number = @enumFromInt(@intFromEnum(sym.section_number)); | 3137 | entry.section_number = @enumFromInt(@intFromEnum(sym.section_number)); |
| ... | @@ -3137,34 +3140,19 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void | ... | @@ -3137,34 +3140,19 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3137 | .base_type = .NULL, | 3140 | .base_type = .NULL, |
| 3138 | }; | 3141 | }; |
| 3139 | | 3142 | |
| 3140 | entry.storage_class = if (sym.flags.extra_tag == .next_alias_si) storage: { | 3143 | entry.storage_class = if (sym.gmi != .none) |
| 3141 | // TODO: Could avoid this ordering issue by flushing these in fifo order, instead of lifo | 3144 | .EXTERNAL |
| 3142 | // TODO: Instead keep a map of si -> sti (remove it from sym.value) and walk in forwards order | 3145 | else if (sym.flags.extra_tag == .next_alias_si) storage: { |
| 3143 | // Update any existing aux symbols for weak externals that reference this symbol | | |
| 3144 | var any_weak_external = false; | | |
| 3145 | var alias_sym = sym; | 3146 | var alias_sym = sym; |
| 3146 | while (alias_sym.flags.extra_tag == .next_alias_si) { | 3147 | const weak_external = while (alias_sym.flags.extra_tag == .next_alias_si) { |
| 3147 | const alias_si = alias_sym.extra.next_alias_si; | 3148 | const alias_si = alias_sym.extra.next_alias_si; |
| 3148 | alias_sym = alias_si.get(coff); | 3149 | alias_sym = alias_si.get(coff); |
| 3149 | assert(alias_sym.ni == sym.ni); | 3150 | assert(alias_sym.ni == sym.ni); |
| 3150 | | 3151 | if (alias_sym.flags.weak_external_strat != .none) |
| 3151 | if (alias_sym.flags.weak_external_strat != .none) { | 3152 | break true; |
| 3152 | switch (alias_sym.flags.value_tag) { | 3153 | } else false; |
| 3153 | .sti => if (coff.symbolTableWeakExternalAuxEntryPtr(alias_si)) |aux_ptr| | 3154 | break :storage if (weak_external) .EXTERNAL else .STATIC; |
| 3154 | coff.targetStore(&aux_ptr.tag_index, sym.value.sti.unwrap().?), | 3155 | } else .STATIC; |
| 3155 | .weak_alias_si => {}, | | |
| 3156 | else => unreachable, | | |
| 3157 | } | | |
| 3158 | | | |
| 3159 | any_weak_external = true; | | |
| 3160 | } | | |
| 3161 | } | | |
| 3162 | | | |
| 3163 | break :storage if (any_weak_external or sym.gmi != .none) .EXTERNAL else .STATIC; | | |
| 3164 | } else if (sym.gmi == .none) | | |
| 3165 | .STATIC | | |
| 3166 | else | | |
| 3167 | .EXTERNAL; | | |
| 3168 | | 3156 | |
| 3169 | entry.number_of_aux_symbols = num_aux_symbols; | 3157 | entry.number_of_aux_symbols = num_aux_symbols; |
| 3170 | if (coff.targetEndian() != native_endian) | 3158 | if (coff.targetEndian() != native_endian) |
| ... | @@ -3175,15 +3163,8 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void | ... | @@ -3175,15 +3163,8 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3175 | entry.section_number = .UNDEFINED; | 3163 | entry.section_number = .UNDEFINED; |
| 3176 | entry.storage_class = .WEAK_EXTERNAL; | 3164 | entry.storage_class = .WEAK_EXTERNAL; |
| 3177 | | 3165 | |
| 3178 | const alias_si = old_value.weak_alias_si; | 3166 | const tag_index = sym.value.weak_alias_si.sti(coff).unwrap().?; |
| 3179 | const alias_sym = alias_si.get(coff); | 3167 | const aux_ptr = coff.symbolTableWeakExternalAuxEntryPtr(sti.*).?; |
| 3180 | const tag_index = alias_sym.value.sti.unwrap() orelse tag_index: { | | |
| 3181 | // The alias will update `tag_index` when it is flushed | | |
| 3182 | assert(coff.symbol_table.pending.contains(alias_si)); | | |
| 3183 | break :tag_index 0; | | |
| 3184 | }; | | |
| 3185 | | | |
| 3186 | const aux_ptr = coff.symbolTableWeakExternalAuxEntryPtr(si).?; | | |
| 3187 | aux_ptr.* = .{ | 3168 | aux_ptr.* = .{ |
| 3188 | .tag_index = tag_index, | 3169 | .tag_index = tag_index, |
| 3189 | .flag = switch (sym.flags.weak_external_strat) { | 3170 | .flag = switch (sym.flags.weak_external_strat) { |
| ... | @@ -3203,7 +3184,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void | ... | @@ -3203,7 +3184,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3203 | .image_section => |sec_si| { | 3184 | .image_section => |sec_si| { |
| 3204 | assert(si == sec_si); | 3185 | assert(si == sec_si); |
| 3205 | const header = sym.section_number.header(coff); | 3186 | const header = sym.section_number.header(coff); |
| 3206 | const aux_ptr = coff.symbolTableSectionAuxEntryPtr(si).?; | 3187 | const aux_ptr = coff.symbolTableSectionAuxEntryPtr(sti.*).?; |
| 3207 | aux_ptr.* = .{ | 3188 | aux_ptr.* = .{ |
| 3208 | .length = @intCast(sym.ni.location(&coff.mf).resolve(&coff.mf)[1]), | 3189 | .length = @intCast(sym.ni.location(&coff.mf).resolve(&coff.mf)[1]), |
| 3209 | .number_of_relocations = header.number_of_relocations, | 3190 | .number_of_relocations = header.number_of_relocations, |
| ... | @@ -3238,7 +3219,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void | ... | @@ -3238,7 +3219,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3238 | }, | 3219 | }, |
| 3239 | }); | 3220 | }); |
| 3240 | | 3221 | |
| 3241 | log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sym.value.sti }); | 3222 | log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sti.* }); |
| 3242 | } | 3223 | } |
| 3243 | | 3224 | |
| 3244 | fn flushInputMember(coff: *Coff, iami: InputArchive.Member.Index) !void { | 3225 | fn flushInputMember(coff: *Coff, iami: InputArchive.Member.Index) !void { |
| ... | @@ -3300,7 +3281,7 @@ fn addSection(coff: *Coff, name: String, flags: std.coff.SectionHeader.Flags) !S | ... | @@ -3300,7 +3281,7 @@ fn addSection(coff: *Coff, name: String, flags: std.coff.SectionHeader.Flags) !S |
| 3300 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 3281 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 3301 | try coff.section_table.ensureUnusedCapacity(gpa, 1); | 3282 | try coff.section_table.ensureUnusedCapacity(gpa, 1); |
| 3302 | try coff.symbols.ensureUnusedCapacity(gpa, 1); | 3283 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 3303 | if (!isImage(coff)) try coff.symbol_table.pending.ensureUnusedCapacity(gpa, 1); | 3284 | if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1); |
| 3304 | | 3285 | |
| 3305 | const coff_header = coff.headerPtr(); | 3286 | const coff_header = coff.headerPtr(); |
| 3306 | const section_index = coff.targetLoad(&coff_header.number_of_sections); | 3287 | const section_index = coff.targetLoad(&coff_header.number_of_sections); |
| ... | @@ -3643,8 +3624,9 @@ pub fn addReloc( | ... | @@ -3643,8 +3624,9 @@ pub fn addReloc( |
| 3643 | else => |loc_sn| sri: { | 3624 | else => |loc_sn| sri: { |
| 3644 | // The target may not have a node yet, or it could be an extern that will never | 3625 | // The target may not have a node yet, or it could be an extern that will never |
| 3645 | // have a node. In that case, flushGlobal will create the symbol table entry. | 3626 | // have a node. In that case, flushGlobal will create the symbol table entry. |
| 3646 | const sti: SymbolTable.Index = if (target.value.sti != .none) | 3627 | const existing_sti = target_si.sti(coff); |
| 3647 | target.value.sti | 3628 | const sti: SymbolTable.Index = if (existing_sti != .none) |
| | 3629 | existing_sti |
| 3648 | else if (target.ni != .none) sti: { | 3630 | else if (target.ni != .none) sti: { |
| 3649 | try coff.pendingSymbolTableEntry(target_si); | 3631 | try coff.pendingSymbolTableEntry(target_si); |
| 3650 | break :sti .none; | 3632 | break :sti .none; |
| ... | @@ -3669,7 +3651,7 @@ pub fn addReloc( | ... | @@ -3669,7 +3651,7 @@ pub fn addReloc( |
| 3669 | } | 3651 | } |
| 3670 | | 3652 | |
| 3671 | coff.targetStore(&header.number_of_relocations, new_num_relocations); | 3653 | coff.targetStore(&header.number_of_relocations, new_num_relocations); |
| 3672 | if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff))) |aux_ptr| | 3654 | if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff).sti(coff))) |aux_ptr| |
| 3673 | coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); | 3655 | coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); |
| 3674 | | 3656 | |
| 3675 | // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?) | 3657 | // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?) |
| ... | @@ -5306,7 +5288,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -5306,7 +5288,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5306 | .none => { | 5288 | .none => { |
| 5307 | const sec_si = try coff.navSection(zcu, nav.resolved.?); | 5289 | const sec_si = try coff.navSection(zcu, nav.resolved.?); |
| 5308 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 5290 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 5309 | if (!isImage(coff)) try coff.symbol_table.pending.ensureUnusedCapacity(gpa, 1); | 5291 | if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1); |
| 5310 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ | 5292 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ |
| 5311 | .alignment = zcu.navAlignment(nav_index).toStdMem(), | 5293 | .alignment = zcu.navAlignment(nav_index).toStdMem(), |
| 5312 | .moved = true, | 5294 | .moved = true, |
| ... | @@ -5428,7 +5410,7 @@ fn updateFuncInner( | ... | @@ -5428,7 +5410,7 @@ fn updateFuncInner( |
| 5428 | .none => { | 5410 | .none => { |
| 5429 | const sec_si = try coff.navSection(zcu, nav.resolved.?); | 5411 | const sec_si = try coff.navSection(zcu, nav.resolved.?); |
| 5430 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 5412 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 5431 | if (!isImage(coff)) try coff.symbol_table.pending.ensureUnusedCapacity(gpa, 1); | 5413 | if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1); |
| 5432 | const mod = zcu.navFileScope(func.owner_nav).mod.?; | 5414 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 5433 | const target = &mod.resolved_target.result; | 5415 | const target = &mod.resolved_target.result; |
| 5434 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ | 5416 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ |
| ... | @@ -5902,19 +5884,21 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -5902,19 +5884,21 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5902 | }; | 5884 | }; |
| 5903 | break :task; | 5885 | break :task; |
| 5904 | }; | 5886 | }; |
| 5905 | while (coff.symbol_table.pending.pop()) |pending_si| { | 5887 | if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) { |
| 5906 | const sym = pending_si.key.get(coff); | 5888 | defer coff.symbol_table.pending_symbol_index += 1; |
| | 5889 | const si = coff.symbol_table.symbols.keys()[coff.symbol_table.pending_symbol_index]; |
| | 5890 | const sym = si.get(coff); |
| 5907 | const sub_prog_node = coff.idleProgNode( | 5891 | const sub_prog_node = coff.idleProgNode( |
| 5908 | tid, | 5892 | tid, |
| 5909 | coff.symbol_prog_node, | 5893 | coff.symbol_prog_node, |
| 5910 | if (sym.ni != .none) | 5894 | if (sym.ni != .none) |
| 5911 | coff.getNode(sym.ni) | 5895 | coff.getNode(sym.ni) |
| 5912 | else | 5896 | else |
| 5913 | .{ .import_thunk = pending_si.key.get(coff).gmi }, | 5897 | .{ .import_thunk = sym.gmi }, |
| 5914 | ); | 5898 | ); |
| 5915 | defer sub_prog_node.end(); | 5899 | defer sub_prog_node.end(); |
| 5916 | coff.flushSymbolTableEntry( | 5900 | coff.flushSymbolTableEntry( |
| 5917 | pending_si.key, | 5901 | coff.symbol_table.pending_symbol_index, |
| 5918 | .{ .zcu = comp.zcu.?, .tid = tid }, | 5902 | .{ .zcu = comp.zcu.?, .tid = tid }, |
| 5919 | ) catch |err| switch (err) { | 5903 | ) catch |err| switch (err) { |
| 5920 | error.OutOfMemory => return error.OutOfMemory, | 5904 | error.OutOfMemory => return error.OutOfMemory, |
| ... | @@ -5935,7 +5919,7 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -5935,7 +5919,7 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5935 | if (coff.exports_complete and coff.late_globals.items.len > coff.late_globals_pending_index) return true; | 5919 | if (coff.exports_complete and coff.late_globals.items.len > coff.late_globals_pending_index) return true; |
| 5936 | if (coff.exports_complete and coff.pending_special_symbol != .none) return true; | 5920 | if (coff.exports_complete and coff.pending_special_symbol != .none) return true; |
| 5937 | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; | 5921 | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; |
| 5938 | if (coff.symbol_table.pending.count() > 0) return true; | 5922 | if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) return true; |
| 5939 | return false; | 5923 | return false; |
| 5940 | } | 5924 | } |
| 5941 | | 5925 | |
| ... | @@ -6066,7 +6050,7 @@ fn flushUav( | ... | @@ -6066,7 +6050,7 @@ fn flushUav( |
| 6066 | .{ .read = true, .initialized = true }, | 6050 | .{ .read = true, .initialized = true }, |
| 6067 | )).symbol(coff); | 6051 | )).symbol(coff); |
| 6068 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 6052 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 6069 | if (!isImage(coff)) try coff.symbol_table.pending.ensureUnusedCapacity(gpa, 1); | 6053 | if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1); |
| 6070 | const sym = si.get(coff); | 6054 | const sym = si.get(coff); |
| 6071 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ | 6055 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ |
| 6072 | .alignment = uav_align.toStdMem(), | 6056 | .alignment = uav_align.toStdMem(), |
| ... | @@ -7012,7 +6996,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -7012,7 +6996,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 7012 | } | 6996 | } |
| 7013 | | 6997 | |
| 7014 | if (!coff.isImage()) { | 6998 | if (!coff.isImage()) { |
| 7015 | if (coff.symbolTableSectionAuxEntryPtr(si)) |aux_ptr| | 6999 | if (coff.symbolTableSectionAuxEntryPtr(si.sti(coff))) |aux_ptr| |
| 7016 | coff.targetStore(&aux_ptr.length, @intCast(size)); | 7000 | coff.targetStore(&aux_ptr.length, @intCast(size)); |
| 7017 | } | 7001 | } |
| 7018 | }, | 7002 | }, |
| ... | @@ -7290,6 +7274,8 @@ fn updateExportsInner( | ... | @@ -7290,6 +7274,8 @@ fn updateExportsInner( |
| 7290 | export_sym.rva = exported_sym.rva; | 7274 | export_sym.rva = exported_sym.rva; |
| 7291 | export_sym.section_number = exported_sym.section_number; | 7275 | export_sym.section_number = exported_sym.section_number; |
| 7292 | if (@"export".opts.linkage == .weak and !coff.isImage()) { | 7276 | if (@"export".opts.linkage == .weak and !coff.isImage()) { |
| | 7277 | // exported_si needs to be ahead of export_si in the symbol table, |
| | 7278 | // so that its sti is known when creating the aux entry |
| 7293 | try coff.pendingSymbolTableEntry(exported_si); | 7279 | try coff.pendingSymbolTableEntry(exported_si); |
| 7294 | export_sym.flags.weak_external_strat = .alias; | 7280 | export_sym.flags.weak_external_strat = .alias; |
| 7295 | export_sym.setValue(.{ .weak_alias_si = exported_si }); | 7281 | export_sym.setValue(.{ .weak_alias_si = exported_si }); |
| ... | @@ -7466,10 +7452,10 @@ fn printSymbol( | ... | @@ -7466,10 +7452,10 @@ fn printSymbol( |
| 7466 | else | 7452 | else |
| 7467 | 0, | 7453 | 0, |
| 7468 | switch (sym.flags.value_tag) { | 7454 | switch (sym.flags.value_tag) { |
| | 7455 | .none => "xx", |
| 7469 | .weak_alias_name => "an", | 7456 | .weak_alias_name => "an", |
| 7470 | .weak_alias_si => "as", | 7457 | .weak_alias_si => "as", |
| 7471 | .node_offset => "no", | 7458 | .node_offset => "no", |
| 7472 | .sti => "st", | | |
| 7473 | }, | 7459 | }, |
| 7474 | switch (sym.flags.extra_tag) { | 7460 | switch (sym.flags.extra_tag) { |
| 7475 | .size => "sz", | 7461 | .size => "sz", |