authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-06-05 01:55:35-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-06-23 00:26:56-04:00
log2f8a3eb4c8f2de68f9337978ab9b628087530c34
tree25dc6c28a670ef3943f77d60c9c8f9759b6c267c
parent2d3d3c042e99da64df53a533852bd0e27166b4f6

Coff: fixup alias list

- Change aliases to a linked list, as they aren't always contiguous

1 files changed, 34 insertions(+), 36 deletions(-)

src/link/Coff.zig+34-36
......@@ -912,7 +912,7 @@ pub const Symbol = struct {
912912 dll_storage_class: DllStorageClass,
913913 // Only defined for .alias_si and .alias_name
914914 weak_external_strat: WeakExternalStrat,
915 has_aliases: bool,
915 has_alias: bool,
916916 _: u7 = 0,
917917 },
918918 /// Relocations contained within this symbol
......@@ -927,9 +927,9 @@ pub const Symbol = struct {
927927 /// Only valid when .ni == .input_section and .value_tag == .node_offset
928928 /// TODO: This is only used for name lookups, could just be String?
929929 isli: Node.InputSection.LocalIndex,
930 /// Only valid if flags.has_aliases is set. The first in a contiguous
931 /// list of symbols that are aliases of this symbol.
932 first_alias_si: Symbol.Index,
930 /// Only valid if flags.has_alias is set.
931 /// The next symbol in the list of aliases of this symbol.
932 next_alias_si: Symbol.Index,
933933 },
934934
935935 pub const DllStorageClass = enum(u2) {
......@@ -1069,13 +1069,13 @@ pub const Symbol = struct {
10691069 si.applyLocationRelocs(coff);
10701070 si.applyTargetRelocs(coff, .none);
10711071
1072 if (sym.flags.has_aliases) {
1073 for (coff.symbols.items[@intFromEnum(sym.extra.first_alias_si)..]) |*export_sym| {
1074 if (export_sym.ni != sym.ni) break;
1075 export_sym.rva = sym.rva;
1076 const export_si: Symbol.Index = @enumFromInt(export_sym - coff.symbols.items.ptr);
1077 export_si.applyTargetRelocs(coff, .none);
1078 }
1072 var alias_sym = sym;
1073 while (alias_sym.flags.has_alias) {
1074 const alias_si = alias_sym.extra.next_alias_si;
1075 alias_sym = alias_si.get(coff);
1076 assert(alias_sym.ni == sym.ni);
1077 alias_sym.rva = sym.rva;
1078 alias_si.applyTargetRelocs(coff, .none);
10791079 }
10801080 }
10811081
......@@ -2028,9 +2028,9 @@ fn initHeaders(
20282028 try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count);
20292029 assert(coff.addSymbolAssumeCapacity() == .null);
20302030
2031 // TODO: How do we tell MappedFile not to allocate physical space for these?
2032 // TODO: Could have a node flag 'virtual' that can never have slice* called on it or fileLocation
2033 // TODO: Instead of it's own section, we can place .bss as a pseudo-section at the end of .text in the extra space
2031 // TODO: How do we tell MappedFile not to allocate physical space for .bss?
2032 // TODO: Could have a node flag 'virtual' that can never have slice* or fileLocation called on it
2033 // TODO: Instead of it's own section, place .bss as a pseudo-section at the end of .text in the extra space
20342034 assert(try coff.addSection(.@".bss", .{
20352035 .CNT_UNINITIALIZED_DATA = true,
20362036 .MEM_READ = true,
......@@ -2203,9 +2203,6 @@ pub fn initBuiltins(coff: *Coff) !void {
22032203 );
22042204
22052205 const start_sym = start_osmi.symbol(coff).get(coff);
2206 start_sym.extra = .{ .first_alias_si = @enumFromInt(coff.symbols.items.len) };
2207 start_sym.flags.has_aliases = true;
2208
22092206 try start_sym.ni.resize(&coff.mf, gpa, addr_info.size);
22102207 const start_slice = start_sym.ni.slice(&coff.mf);
22112208 switch (addr_info.magic) {
......@@ -2229,6 +2226,9 @@ pub fn initBuiltins(coff: *Coff) !void {
22292226 const list_sym = list_si.get(coff);
22302227 list_sym.ni = start_sym.ni;
22312228 list_sym.section_number = start_sym.section_number;
2229
2230 start_sym.extra = .{ .next_alias_si = list_si };
2231 start_sym.flags.has_alias = true;
22322232 }
22332233 }
22342234}
......@@ -2564,7 +2564,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index {
25642564 .type = .unknown,
25652565 .dll_storage_class = .default,
25662566 .weak_external_strat = undefined,
2567 .has_aliases = false,
2567 .has_alias = false,
25682568 },
25692569 .loc_relocs = .none,
25702570 .target_relocs = .none,
......@@ -2692,10 +2692,6 @@ fn getDefinedGlobal(coff: *Coff, name: []const u8) Symbol.Index {
26922692
26932693pub fn globalSymbol(coff: *Coff, opts: GlobalOptions) !Symbol.Index {
26942694 const gop = try coff.getOrPutGlobalSymbol(opts);
2695 if (gop.found_existing) {
2696 // TODO: Need to know if this is an export or extern, in order to decide if this is duplicate, add to opts
2697 }
2698
26992695 return gop.value_ptr.*;
27002696}
27012697
......@@ -3525,7 +3521,6 @@ pub fn addReloc(
35253521 );
35263522
35273523 // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?)
3528
35293524 const sri: Section.RelocationIndex = .wrap(old_num_relocations);
35303525 const entry = sri.entry(coff, loc_sn).?;
35313526 if (sti.unwrap()) |index| coff.targetStore(&entry.symbol_table_index, index);
......@@ -3826,7 +3821,7 @@ fn loadObject(
38263821 try member.initHeader(coff, path_str, header.time_date_stamp);
38273822
38283823 {
3829 // TODO: This could be deferred to an idle task?
3824 // TODO: This should be deferred to an idle task
38303825 var nw: MappedFile.Node.Writer = undefined;
38313826 member.content_ni.writer(&coff.mf, gpa, &nw);
38323827 defer nw.deinit();
......@@ -4101,7 +4096,7 @@ fn loadObject(
41014096 if (arg.len == 0) continue;
41024097
41034098 if (std.ascii.startsWithIgnoreCase(arg, "-exclude-symbols:")) {
4104 // TODO: When implementing mingw auto-exports (if at all?), use this to not export this symbol
4099 // TODO: When implementing mingw auto-exports (if at all?), track this to not export this symbol
41054100 } else if (std.ascii.startsWithIgnoreCase(arg, "/include:")) {
41064101 _ = try coff.globalSymbol(.{ .name = arg["/include:".len..] });
41074102 } else if (std.ascii.startsWithIgnoreCase(arg, "/alternatename:")) {
......@@ -4251,7 +4246,7 @@ fn loadObject(
42514246 .lib_name = null,
42524247 });
42534248
4254 // TODO: What if the same symbol defined twice in this obj?
4249 // TODO: What if the same symbol is incorrectly defined twice in this obj?
42554250 // TODO: Would need to mark this global as pending, or notice it later when .ni != none
42564251 if (!global_gop.found_existing or global_gop.value_ptr.get(coff).ni == .none) {
42574252 symbol.si = global_gop.value_ptr.*;
......@@ -4319,7 +4314,7 @@ fn loadObject(
43194314 .LARGEST => {
43204315 // TODO: Resize existing .ni and replace with this section's contents
43214316 // TODO: This will be tricky, what to do about existing InputSection?
4322 unreachable; // TODO
4317 unreachable;
43234318 },
43244319 .NONE, .ASSOCIATIVE, _ => unreachable,
43254320 }
......@@ -4504,7 +4499,7 @@ fn loadObject(
45044499 symbol.si = coff.addSymbolAssumeCapacity();
45054500 },
45064501 .external => {
4507 // TODO: Assert this is not the comdat leader
4502 assert(index != section.comdat_psi.unwrap());
45084503 const global_gop = try coff.getOrPutGlobalSymbol(.{ .name = symbol.name.toSlice(coff) });
45094504 symbol.si = global_gop.value_ptr.*;
45104505
......@@ -5017,7 +5012,7 @@ fn loadArchive(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !vo
50175012 } else {
50185013 member.content.object.size = res.size;
50195014 // TODO: If .UNKNOWN assert later that it contains no non-undef symbols?
5020 // Microsoft's CRT contains members that set .UNKNOWN but do have symbols
5015 // Microsoft's CRT contains members that set .UNKNOWN but do have undef symbols
50215016 if (machine != expected_machine and machine != .UNKNOWN) {
50225017 return diags.failParse(path, "machine mismatch in member header '{s}': expected {t}, found {t}", .{
50235018 res.name,
......@@ -5192,7 +5187,6 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
51925187 si.applyLocationRelocs(coff);
51935188 }
51945189
5195 // TODO: Did my MappedFile resize change affect this?
51965190 if (nav.resolved.?.@"linksection".unwrap()) |_| {
51975191 try ni.resize(&coff.mf, gpa, si.get(coff).value.size);
51985192 var parent_ni = ni;
......@@ -5746,7 +5740,7 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
57465740 };
57475741 break :task;
57485742 }
5749 // TODO: Idle task for flushing obj into lib?
5743 // TODO: Idle task for flushing obj into lib
57505744 if (coff.input_section_pending_index < coff.input_sections.items.len) {
57515745 const isi: Node.InputSection.Index = @enumFromInt(coff.input_section_pending_index);
57525746 coff.input_section_pending_index += 1;
......@@ -7087,14 +7081,11 @@ fn updateExportsInner(
70877081 Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu),
70887082 ))),
70897083 };
7090 while (try coff.idle(pt.tid)) {} // TODO: Is this necessary now that we handle exports moving via has_aliases?
70917084
70927085 const machine = coff.targetLoad(&coff.headerPtr().machine);
70937086 const exported_ni = exported_si.node(coff);
70947087 const exported_sym = exported_si.get(coff);
7095 exported_sym.extra = .{ .first_alias_si = @enumFromInt(coff.symbols.items.len) };
7096 exported_sym.flags.has_aliases = true;
7097
7088 var prev_alias_si = exported_si;
70987089 for (export_indices) |export_index| {
70997090 const @"export" = export_index.ptr(zcu);
71007091 const name = @"export".opts.name.toSlice(ip);
......@@ -7111,6 +7102,12 @@ fn updateExportsInner(
71117102 export_sym.section_number = exported_sym.section_number;
71127103 defer export_si.applyTargetRelocs(coff, .none);
71137104
7105 const prev_alias_sym = prev_alias_si.get(coff);
7106 assert(!prev_alias_sym.flags.has_alias);
7107 prev_alias_sym.extra = .{ .next_alias_si = export_si };
7108 prev_alias_sym.flags.has_alias = true;
7109 prev_alias_si = export_si;
7110
71147111 if (!coff.isImage()) continue;
71157112
71167113 const entries_ctx = ExportTable.Adapter{ .coff = coff };
......@@ -7153,7 +7150,8 @@ fn updateExportsInner(
71537150 coff.targetStore(&edt.number_of_names, @intCast(export_count));
71547151 edt.number_of_entries = edt.number_of_names;
71557152
7156 // TODO: These should all be resized ahead of time to fit all exports (after https://github.com/ziglang/zig/issues/23616)
7153 // TODO: These should all be resized ahead of time to fit all exports
7154 // after https://github.com/ziglang/zig/issues/23616
71577155 try coff.export_table.export_address_table_si.node(coff).resize(
71587156 &coff.mf,
71597157 gpa,