authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-06-05 01:55:36-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-06-23 00:27:16-04:00
log7be8e660acaa56d2be110d59b058ff2a31b05e23
tree73d3c9f58ba6266373eb40474032b27d98d0ece4
parent2c3f42724d5131d826674357cecb5731d858ad27

Coff: value / extra rework to allow symbols to have both an alias and symbol table entry

Coff: move pending_shrink handling to flush, as it's a special case of a resolve task that generates idle tasks (moves / resizes). It's also redundant to do this operation more than once.

1 files changed, 152 insertions(+), 108 deletions(-)

src/link/Coff.zig+152-108
......@@ -874,14 +874,15 @@ pub const Symbol = struct {
874874 ni: MappedFile.Node.Index,
875875 rva: u32,
876876 value: std.meta.BareUnion(Symbol.Value),
877 extra: std.meta.BareUnion(Symbol.Extra),
877878 flags: packed struct(u16) {
878879 value_tag: ValueTag,
880 extra_tag: ExtraTag,
879881 type: Symbol.Type,
880882 dll_storage_class: DllStorageClass,
881883 // Only defined for .alias_si and .alias_name
882884 weak_external_strat: WeakExternalStrat,
883 has_alias: bool,
884 _: u7 = 0,
885 _: u6 = 0,
885886 },
886887 /// Relocations contained within this symbol
887888 loc_relocs: Reloc.Index,
......@@ -889,16 +890,6 @@ pub const Symbol = struct {
889890 target_relocs: Reloc.Index,
890891 section_number: SectionNumber,
891892 gmi: Node.GlobalMapIndex,
892 extra: union {
893 /// Only valid when outputting objects
894 sti: SymbolTable.Index,
895 /// Only valid when .ni == .input_section and .value_tag == .node_offset
896 /// TODO: This is only used for name lookups, could just be String?
897 isli: Node.InputSection.LocalIndex,
898 /// Only valid if flags.has_alias is set.
899 /// The next symbol in the list of aliases of this symbol.
900 next_alias_si: Symbol.Index,
901 },
902893
903894 pub const DllStorageClass = enum(u2) {
904895 default,
......@@ -916,23 +907,41 @@ pub const Symbol = struct {
916907 node_offset,
917908 weak_alias_si,
918909 weak_alias_name,
919 size,
910 sti,
920911 };
921912
922913 pub const Value = union(ValueTag) {
923914 /// The offset of the symbol within its node. Used with symbols that
924915 /// don't create their own nodes: .input_section, .import_address_table
916 /// Images only.
925917 node_offset: u32,
926918 /// This is a weak alias that can replace this symbol
927 /// Globals only.
919 /// Globals only, images only.
928920 weak_alias_si: Symbol.Index,
929921 /// For weak externals that have an alias that is also an undef
930922 /// external, this is the name of the alias global that should
931923 /// be generated if this symbol is not resolved.
932 /// Globals only.
924 /// Globals only, images only.
933925 weak_alias_name: String,
934 /// The symbol size, or 0 if unknown
926 /// Index of this symbol in the symbol table
927 /// Only used when outputting objects
928 sti: SymbolTable.Index,
929 };
930
931 const ExtraTag = enum(u2) {
932 size,
933 isli,
934 next_alias_si,
935 };
936
937 pub const Extra = union(ExtraTag) {
938 // The size of the symbol
935939 size: u32,
940 /// Only valid when .ni == .input_section and .value_tag == .node_offset
941 /// TODO: This is only used for name lookups, could just be String?
942 isli: Node.InputSection.LocalIndex,
943 /// The next symbol in the list of aliases of this symbol.
944 next_alias_si: Symbol.Index,
936945 };
937946
938947 pub fn setValue(sym: *Symbol, value: Symbol.Value) void {
......@@ -946,6 +955,17 @@ pub const Symbol = struct {
946955 };
947956 }
948957
958 pub fn setExtra(sym: *Symbol, extra: Symbol.Extra) void {
959 sym.flags.extra_tag = std.meta.activeTag(extra);
960 sym.extra = switch (sym.flags.extra_tag) {
961 inline else => |t| @unionInit(
962 @FieldType(Symbol, "extra"),
963 @tagName(t),
964 @field(extra, @tagName(t)),
965 ),
966 };
967 }
968
949969 pub fn nodeOffset(sym: *const Symbol, coff: *Coff) u32 {
950970 return switch (sym.flags.value_tag) {
951971 .node_offset => offset: {
......@@ -961,7 +981,7 @@ pub const Symbol = struct {
961981 }
962982
963983 pub fn size(sym: *const Symbol) u32 {
964 return if (sym.flags.value_tag == .size) sym.value.size else 0;
984 return if (sym.flags.extra_tag == .size) sym.extra.size else 0;
965985 }
966986
967987 pub const SectionNumber = enum(i16) {
......@@ -1038,7 +1058,7 @@ pub const Symbol = struct {
10381058 si.applyTargetRelocs(coff, .none);
10391059
10401060 var alias_sym = sym;
1041 while (alias_sym.flags.has_alias) {
1061 while (alias_sym.flags.extra_tag == .next_alias_si) {
10421062 const alias_si = alias_sym.extra.next_alias_si;
10431063 alias_sym = alias_si.get(coff);
10441064 assert(alias_sym.ni == sym.ni);
......@@ -1049,7 +1069,7 @@ pub const Symbol = struct {
10491069
10501070 pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void {
10511071 const sym = si.get(coff);
1052 const index = sym.extra.sti.unwrap() orelse return;
1072 const index = sym.value.sti.unwrap() orelse return;
10531073 var ri = sym.target_relocs;
10541074 while (ri != .none) {
10551075 const reloc = ri.get(coff);
......@@ -1989,6 +2009,7 @@ fn initHeaders(
19892009 .resized = true,
19902010 });
19912011 coff.nodes.appendAssumeCapacity(.string_table);
2012 coff.targetStore(coff.symbolTableStringLenPtr(), @sizeOf(u32));
19922013 }
19932014
19942015 try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count);
......@@ -2193,8 +2214,7 @@ pub fn initBuiltins(coff: *Coff) !void {
21932214 list_sym.ni = start_sym.ni;
21942215 list_sym.section_number = start_sym.section_number;
21952216
2196 start_sym.extra = .{ .next_alias_si = list_si };
2197 start_sym.flags.has_alias = true;
2217 start_sym.setExtra(.{ .next_alias_si = list_si });
21982218 }
21992219 }
22002220}
......@@ -2483,11 +2503,14 @@ pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.c
24832503 return null;
24842504}
24852505
2486pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) *align(2) std.coff.SectionDefinition {
2487 const sti = si.get(coff).extra.sti;
2488 const entry = symbolTableEntryPtr(coff, sti).?;
2489 assert(entry.storage_class == .STATIC and entry.number_of_aux_symbols == 1);
2490 return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1)));
2506pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) ?*align(2) std.coff.SectionDefinition {
2507 const sti = si.get(coff).value.sti;
2508 if (symbolTableEntryPtr(coff, sti)) |entry| {
2509 assert(entry.storage_class == .STATIC and entry.number_of_aux_symbols == 1);
2510 return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1)));
2511 } else {
2512 return null;
2513 }
24912514}
24922515
24932516pub fn symbolTableStringLenPtr(coff: *Coff) *align(1) u32 {
......@@ -2524,19 +2547,19 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index {
25242547 defer coff.symbols.addOneAssumeCapacity().* = .{
25252548 .ni = .none,
25262549 .rva = 0,
2527 .value = .{ .size = 0 },
2550 .value = .{ .sti = .none },
2551 .extra = .{ .size = 0 },
25282552 .flags = .{
2529 .value_tag = .size,
2553 .value_tag = .sti,
2554 .extra_tag = .size,
25302555 .type = .unknown,
25312556 .dll_storage_class = .default,
25322557 .weak_external_strat = undefined,
2533 .has_alias = false,
25342558 },
25352559 .loc_relocs = .none,
25362560 .target_relocs = .none,
25372561 .section_number = .UNDEFINED,
25382562 .gmi = .none,
2539 .extra = .{ .sti = .none },
25402563 };
25412564 return @enumFromInt(coff.symbols.items.len);
25422565}
......@@ -2975,7 +2998,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void
29752998 const sym = si.get(coff);
29762999 assert(sym.ni != .none or sym.gmi != .none);
29773000
2978 const entry = coff.symbolTableEntryPtr(sym.extra.sti) orelse entry: {
3001 const entry = coff.symbolTableEntryPtr(sym.value.sti) orelse entry: {
29793002 var buf: [15]u8 = undefined;
29803003 const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType =
29813004 if (sym.gmi != .none) blk: {
......@@ -3040,10 +3063,11 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void
30403063 try coff.symbol_table.ni.resize(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf());
30413064
30423065 coff.targetStore(&coff.headerPtr().number_of_symbols, new_num_symbols);
3043 sym.extra = .{ .sti = .wrap(old_num_symbols) };
3066
3067 sym.value.sti = .wrap(old_num_symbols);
30443068 si.flushSymbolTableIndex(coff);
30453069
3046 const entry = coff.symbolTableEntryPtr(sym.extra.sti).?;
3070 const entry = coff.symbolTableEntryPtr(sym.value.sti).?;
30473071 symbol_name.store(coff, &entry.name);
30483072
30493073 entry.section_number = @enumFromInt(@intFromEnum(sym.section_number));
......@@ -3056,8 +3080,31 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void
30563080 if (coff.targetEndian() != native_endian)
30573081 std.mem.byteSwapAllFieldsAligned(std.coff.Symbol, .@"2", entry);
30583082
3059 for (1..num_aux_symbols + 1) |aux_index|
3060 @memset(coff.symbolTableEntryStoragePtr(@intCast(old_num_symbols + aux_index)), 0);
3083 if (num_aux_symbols > 0) aux_init: {
3084 if (sym.gmi == .none) switch (coff.getNode(sym.ni)) {
3085 .image_section => |sec_si| {
3086 assert(si == sec_si);
3087 const header = sym.section_number.header(coff);
3088 const aux_ptr = coff.symbolTableSectionAuxEntryPtr(si).?;
3089 aux_ptr.* = .{
3090 .length = @intCast(sym.ni.location(&coff.mf).resolve(&coff.mf)[1]),
3091 .number_of_relocations = header.number_of_relocations,
3092 .number_of_linenumbers = header.number_of_linenumbers,
3093 .checksum = 0,
3094 .number = 0,
3095 .selection = .NONE,
3096 .unused = @splat(0),
3097 };
3098 if (coff.targetEndian() != native_endian)
3099 std.mem.byteSwapAllFields(std.coff.SectionDefinition, .@"2", aux_ptr);
3100
3101 break :aux_init;
3102 },
3103 else => {},
3104 };
3105
3106 unreachable;
3107 }
30613108
30623109 break :entry entry;
30633110 };
......@@ -3073,7 +3120,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void
30733120 },
30743121 });
30753122
3076 log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sym.extra.sti });
3123 log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sym.value.sti });
30773124}
30783125
30793126fn flushInputMember(coff: *Coff, iami: InputArchive.Member.Index) !void {
......@@ -3478,8 +3525,8 @@ pub fn addReloc(
34783525 else => |loc_sn| sri: {
34793526 // The target may not have a node yet, or it could be an extern that will never
34803527 // have a node. In that case, flushGlobal will create the symbol table entry.
3481 const sti: SymbolTable.Index = if (target.extra.sti != .none)
3482 target.extra.sti
3528 const sti: SymbolTable.Index = if (target.value.sti != .none)
3529 target.value.sti
34833530 else if (target.ni != .none) sti: {
34843531 try coff.pendingSymbolTableEntry(target_si);
34853532 break :sti .none;
......@@ -3503,14 +3550,9 @@ pub fn addReloc(
35033550 try section.relocation_table_ni.resize(&coff.mf, gpa, new_size);
35043551 }
35053552
3506 coff.targetStore(
3507 &header.number_of_relocations,
3508 new_num_relocations,
3509 );
3510 coff.targetStore(
3511 &coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff)).number_of_relocations,
3512 new_num_relocations,
3513 );
3553 coff.targetStore(&header.number_of_relocations, new_num_relocations);
3554 if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff))) |aux_ptr|
3555 coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations);
35143556
35153557 // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?)
35163558 const sri: Section.RelocationIndex = .wrap(old_num_relocations);
......@@ -3643,7 +3685,7 @@ fn loadObject(
36433685
36443686 log.debug("loadObject({f}{f})", .{ path.fmtEscapeString(), fmtMemberNameString(member_name) });
36453687
3646 const header = try r.peekStruct(std.coff.Header, .little());
3688 const header = try r.peekStruct(std.coff.Header, .little);
36473689 if (header.machine != target.toCoffMachine())
36483690 return diags.failParse(path, "machine mismatch: expected {t}, found {t}", .{
36493691 target.toCoffMachine(),
......@@ -3678,7 +3720,7 @@ fn loadObject(
36783720 const string_table_len = try r.peekInt(u32, target_endian);
36793721 if (string_table_len < @sizeOf(u32) or
36803722 symbol_table_end + string_table_len > fl.size)
3681 return diags.failParse(path, "bad string table", .{});
3723 return diags.failParse(path, "bad string table length: 0x{x}", .{string_table_len});
36823724
36833725 const ioi: InputObject.Index = @enumFromInt(coff.input_objects.items.len);
36843726 try coff.input_objects.ensureUnusedCapacity(gpa, 1);
......@@ -4519,17 +4561,18 @@ fn loadObject(
45194561 const sym = symbol.si.get(coff);
45204562 assert(sym.ni == .none);
45214563 sym.ni = section.si.get(coff).ni;
4522 sym.setValue(switch (symbol.value) {
4523 .section => |v| .{ .size = v },
4524 .static => |v| .{ .node_offset = v },
4564 switch (symbol.value) {
4565 .section => |v| sym.setExtra(.{ .size = v }),
4566 .static => |v| sym.setValue(.{ .node_offset = v }),
45254567 .external => |v| switch (symbol.section_number) {
45264568 .UNDEFINED, .ABSOLUTE, .DEBUG => unreachable,
4527 else => .{ .node_offset = v },
4569 else => sym.setValue(.{ .node_offset = v }),
45284570 },
45294571 .weak_external,
45304572 .weak_external_aux,
45314573 => unreachable,
4532 });
4574 }
4575
45334576 sym.section_number = section.si.get(coff).section_number;
45344577 }
45354578 }
......@@ -4572,7 +4615,7 @@ fn loadObject(
45724615 symbol.si = global_gop.value_ptr.*;
45734616 if (!global_gop.found_existing or symbol.si.get(coff).ni == .none) {
45744617 const sym = symbol.si.get(coff);
4575 sym.setValue(.{ .size = @max(sym.size(), size) });
4618 sym.setExtra(.{ .size = @max(sym.size(), size) });
45764619 }
45774620 },
45784621 else => unreachable,
......@@ -5156,12 +5199,12 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
51565199 error.WriteFailed => return nw.err.?,
51575200 else => |e| return e,
51585201 };
5159 si.get(coff).value.size = @intCast(nw.interface.end);
5202 si.get(coff).extra.size = @intCast(nw.interface.end);
51605203 si.applyLocationRelocs(coff);
51615204 }
51625205
51635206 if (nav.resolved.?.@"linksection".unwrap()) |_| {
5164 try ni.resize(&coff.mf, gpa, si.get(coff).value.size);
5207 try ni.resize(&coff.mf, gpa, si.get(coff).extra.size);
51655208 var parent_ni = ni;
51665209 while (true) {
51675210 parent_ni = parent_ni.parent(&coff.mf);
......@@ -5289,7 +5332,7 @@ fn updateFuncInner(
52895332 error.WriteFailed => return nw.err.?,
52905333 else => |e| return e,
52915334 };
5292 si.get(coff).value.size = @intCast(nw.interface.end);
5335 si.get(coff).extra.size = @intCast(nw.interface.end);
52935336 si.applyLocationRelocs(coff);
52945337}
52955338
......@@ -5533,6 +5576,7 @@ pub fn flush(
55335576) !void {
55345577 _ = arena;
55355578 _ = prog_node;
5579 const comp = coff.base.comp;
55365580
55375581 // TODO: When https://github.com/ziglang/zig/issues/23617 is in,
55385582 // this should be set after updateExports instead
......@@ -5541,11 +5585,30 @@ pub fn flush(
55415585 while (try coff.resolve(tid)) {}
55425586 while (try coff.idle(tid)) {}
55435587
5588 // This has to occur after all other flushMoved / flushResized have resolved,
5589 // but it will also generate one more set of resizes and moves.
5590 if (coff.symbol_table.pending_shrink) {
5591 coff.symbol_table.pending_shrink = false;
5592
5593 const number_of_symbols = coff.targetLoad(&coff.headerPtr().number_of_symbols);
5594 coff.symbol_table.ni.shrink(
5595 &coff.mf,
5596 comp.gpa,
5597 number_of_symbols * std.coff.Symbol.sizeOf(),
5598 true,
5599 ) catch |err| switch (err) {
5600 error.OutOfMemory => return error.OutOfMemory,
5601 else => |e| return comp.link_diags.fail(
5602 "linker failed to compact symbol table: {t}",
5603 .{e},
5604 ),
5605 };
5606 }
5607 while (try coff.idle(tid)) {}
5608
55445609 if (coff.isImage())
55455610 try coff.reportUndefs(tid);
55465611
5547 const comp = coff.base.comp;
5548
55495612 // Implib generation should instead be done via building a MappedFile progressively
55505613 if (comp.emit_implib) |implib_file|
55515614 coff.flushImplib(implib_file) catch |err|
......@@ -5717,31 +5780,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
57175780 };
57185781 break :task;
57195782 }
5720 if (coff.symbol_table.pending_shrink) {
5721 defer coff.symbol_table.pending_shrink = false;
5722 const sub_prog_node = coff.idleProgNode(
5723 tid,
5724 coff.symbol_prog_node,
5725 coff.getNode(coff.symbol_table.ni),
5726 );
5727 defer sub_prog_node.end();
5728
5729 const number_of_symbols = coff.targetLoad(&coff.headerPtr().number_of_symbols);
5730 coff.symbol_table.ni.shrink(
5731 &coff.mf,
5732 comp.gpa,
5733 number_of_symbols * std.coff.Symbol.sizeOf(),
5734 true,
5735 ) catch |err| switch (err) {
5736 error.OutOfMemory => return error.OutOfMemory,
5737 else => |e| return comp.link_diags.fail(
5738 "linker failed to compact symbol table: {t}",
5739 .{e},
5740 ),
5741 };
5742
5743 break :task;
5744 }
57455783 }
57465784
57475785 if (coff.section_merge_pending_index < coff.section_merges.count()) return true;
......@@ -5753,7 +5791,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
57535791 if (coff.exports_complete and coff.pending_special_symbol != .none) return true;
57545792 for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true;
57555793 if (coff.symbol_table.pending.count() > 0) return true;
5756 if (coff.symbol_table.pending_shrink) return true;
57575794 return false;
57585795}
57595796
......@@ -5922,7 +5959,7 @@ fn flushUav(
59225959 error.WriteFailed => return nw.err.?,
59235960 else => |e| return e,
59245961 };
5925 si.get(coff).value.size = @intCast(nw.interface.end);
5962 si.get(coff).extra.size = @intCast(nw.interface.end);
59265963 si.applyLocationRelocs(coff);
59275964}
59285965
......@@ -6358,7 +6395,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
63586395 });
63596396 @memcpy(ni.slice(&coff.mf)[0..init.len], &init);
63606397 sym.ni = ni;
6361 sym.setValue(.{ .size = init.len });
6398 sym.extra.size = init.len;
63626399 try coff.addReloc(
63636400 si,
63646401 init.len - 4,
......@@ -6539,7 +6576,7 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
65396576 error.WriteFailed => return nw.err.?,
65406577 else => |e| return e,
65416578 };
6542 si.get(coff).value.size = @intCast(nw.interface.end);
6579 si.get(coff).extra.size = @intCast(nw.interface.end);
65436580 si.applyLocationRelocs(coff);
65446581}
65456582
......@@ -6556,13 +6593,15 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void {
65566593 .section_table,
65576594 .placeholder,
65586595 => assert(!coff.isImage()),
6559 .symbol_table => {
6560 coff.targetStore(
6561 &coff.headerPtr().pointer_to_symbol_table,
6562 @intCast(ni.location(&coff.mf).resolve(&coff.mf)[0]),
6563 );
6564 },
6565 .string_table => {
6596 .symbol_table,
6597 .string_table,
6598 => |_, tag| {
6599 if (tag == .symbol_table)
6600 coff.targetStore(
6601 &coff.headerPtr().pointer_to_symbol_table,
6602 @intCast(ni.location(&coff.mf).resolve(&coff.mf)[0]),
6603 );
6604
65666605 if (!coff.symbol_table.pending_shrink) {
65676606 const symbol_table_loc, const symbol_table_size = coff.symbol_table.ni.location(&coff.mf).resolve(&coff.mf);
65686607 const string_table_offset, _ = coff.symbol_table.strings_ni.location(&coff.mf).resolve(&coff.mf);
......@@ -6822,10 +6861,8 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void {
68226861 }
68236862
68246863 if (!coff.isImage()) {
6825 coff.targetStore(
6826 &coff.symbolTableSectionAuxEntryPtr(si).length,
6827 @intCast(size),
6828 );
6864 if (coff.symbolTableSectionAuxEntryPtr(si)) |aux_ptr|
6865 coff.targetStore(&aux_ptr.length, @intCast(size));
68296866 }
68306867 },
68316868 .input_section => {},
......@@ -6853,7 +6890,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void {
68536890 );
68546891 }
68556892
6856 smi.symbol(coff).get(coff).value.size = @intCast(size);
6893 smi.symbol(coff).get(coff).extra.size = @intCast(size);
68576894 },
68586895 .import_thunk,
68596896 .nav,
......@@ -7091,14 +7128,16 @@ fn updateExportsInner(
70917128 const export_sym = export_si.get(coff);
70927129 export_sym.ni = exported_ni;
70937130 export_sym.rva = exported_sym.rva;
7094 export_sym.setValue(.{ .size = exported_sym.value.size });
70957131 export_sym.section_number = exported_sym.section_number;
70967132 defer export_si.applyTargetRelocs(coff, .none);
70977133
70987134 const prev_alias_sym = prev_alias_si.get(coff);
7099 assert(!prev_alias_sym.flags.has_alias);
7100 prev_alias_sym.extra = .{ .next_alias_si = export_si };
7101 prev_alias_sym.flags.has_alias = true;
7135 switch (prev_alias_sym.flags.extra_tag) {
7136 .size => export_sym.setExtra(.{ .size = prev_alias_sym.extra.size }),
7137 else => unreachable,
7138 }
7139
7140 prev_alias_sym.setExtra(.{ .next_alias_si = export_si });
71027141 prev_alias_si = export_si;
71037142
71047143 if (!coff.isImage()) continue;
......@@ -7237,7 +7276,7 @@ fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) !voi
72377276 try w.print("{d:0>6}@{d:0>2} {x:08} n{d:0>8} | {s}\n", .{
72387277 si,
72397278 sym.section_number,
7240 if (sym.flags.value_tag == .size) sym.value.size else 0,
7279 if (sym.flags.extra_tag == .size) sym.extra.size else 0,
72417280 sym.ni,
72427281 name.toSlice(coff),
72437282 });
......@@ -7251,11 +7290,11 @@ fn printSymbol(
72517290) !void {
72527291 const sym = si.get(coff);
72537292 const node = coff.getNode(sym.ni);
7254 try w.print("{d:0>6}@{d:0>2} {x:08} {s} {s} n{d:0>8}+{x:08}:{t: <26} | {x:08} ", .{
7293 try w.print("{d:0>6}@{d:0>2} {x:08} {s} {s} {s} n{d:0>8}+{x:08}:{t: <26} | {x:08} ", .{
72557294 si,
72567295 sym.section_number,
7257 if (sym.flags.value_tag == .size)
7258 @as(u64, sym.value.size)
7296 if (sym.flags.extra_tag == .size)
7297 @as(u64, sym.extra.size)
72597298 else if (sym.ni != .none)
72607299 sym.ni.location(&coff.mf).resolve(&coff.mf)[1]
72617300 else
......@@ -7264,7 +7303,12 @@ fn printSymbol(
72647303 .weak_alias_name => "an",
72657304 .weak_alias_si => "as",
72667305 .node_offset => "no",
7306 .sti => "st",
7307 },
7308 switch (sym.flags.extra_tag) {
72677309 .size => "sz",
7310 .isli => "li",
7311 .next_alias_si => "na",
72687312 },
72697313 switch (sym.flags.type) {
72707314 .unknown => "u",