| ... | @@ -912,7 +912,7 @@ pub const Symbol = struct { | ... | @@ -912,7 +912,7 @@ pub const Symbol = struct { |
| 912 | dll_storage_class: DllStorageClass, | 912 | dll_storage_class: DllStorageClass, |
| 913 | // Only defined for .alias_si and .alias_name | 913 | // Only defined for .alias_si and .alias_name |
| 914 | weak_external_strat: WeakExternalStrat, | 914 | weak_external_strat: WeakExternalStrat, |
| 915 | has_aliases: bool, | 915 | has_alias: bool, |
| 916 | _: u7 = 0, | 916 | _: u7 = 0, |
| 917 | }, | 917 | }, |
| 918 | /// Relocations contained within this symbol | 918 | /// Relocations contained within this symbol |
| ... | @@ -927,9 +927,9 @@ pub const Symbol = struct { | ... | @@ -927,9 +927,9 @@ pub const Symbol = struct { |
| 927 | /// Only valid when .ni == .input_section and .value_tag == .node_offset | 927 | /// Only valid when .ni == .input_section and .value_tag == .node_offset |
| 928 | /// TODO: This is only used for name lookups, could just be String? | 928 | /// TODO: This is only used for name lookups, could just be String? |
| 929 | isli: Node.InputSection.LocalIndex, | 929 | isli: Node.InputSection.LocalIndex, |
| 930 | /// Only valid if flags.has_aliases is set. The first in a contiguous | 930 | /// Only valid if flags.has_alias is set. |
| 931 | /// list of symbols that are aliases of this symbol. | 931 | /// The next symbol in the list of aliases of this symbol. |
| 932 | first_alias_si: Symbol.Index, | 932 | next_alias_si: Symbol.Index, |
| 933 | }, | 933 | }, |
| 934 | | 934 | |
| 935 | pub const DllStorageClass = enum(u2) { | 935 | pub const DllStorageClass = enum(u2) { |
| ... | @@ -1069,13 +1069,13 @@ pub const Symbol = struct { | ... | @@ -1069,13 +1069,13 @@ pub const Symbol = struct { |
| 1069 | si.applyLocationRelocs(coff); | 1069 | si.applyLocationRelocs(coff); |
| 1070 | si.applyTargetRelocs(coff, .none); | 1070 | si.applyTargetRelocs(coff, .none); |
| 1071 | | 1071 | |
| 1072 | if (sym.flags.has_aliases) { | 1072 | var alias_sym = sym; |
| 1073 | for (coff.symbols.items[@intFromEnum(sym.extra.first_alias_si)..]) |*export_sym| { | 1073 | while (alias_sym.flags.has_alias) { |
| 1074 | if (export_sym.ni != sym.ni) break; | 1074 | const alias_si = alias_sym.extra.next_alias_si; |
| 1075 | export_sym.rva = sym.rva; | 1075 | alias_sym = alias_si.get(coff); |
| 1076 | const export_si: Symbol.Index = @enumFromInt(export_sym - coff.symbols.items.ptr); | 1076 | assert(alias_sym.ni == sym.ni); |
| 1077 | export_si.applyTargetRelocs(coff, .none); | 1077 | alias_sym.rva = sym.rva; |
| 1078 | } | 1078 | alias_si.applyTargetRelocs(coff, .none); |
| 1079 | } | 1079 | } |
| 1080 | } | 1080 | } |
| 1081 | | 1081 | |
| ... | @@ -2028,9 +2028,9 @@ fn initHeaders( | ... | @@ -2028,9 +2028,9 @@ fn initHeaders( |
| 2028 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); | 2028 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); |
| 2029 | assert(coff.addSymbolAssumeCapacity() == .null); | 2029 | assert(coff.addSymbolAssumeCapacity() == .null); |
| 2030 | | 2030 | |
| 2031 | // TODO: How do we tell MappedFile not to allocate physical space for these? | 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* called on it or fileLocation | 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, we can place .bss as a pseudo-section at the end of .text in the extra space | 2033 | // TODO: Instead of it's own section, place .bss as a pseudo-section at the end of .text in the extra space |
| 2034 | assert(try coff.addSection(.@".bss", .{ | 2034 | assert(try coff.addSection(.@".bss", .{ |
| 2035 | .CNT_UNINITIALIZED_DATA = true, | 2035 | .CNT_UNINITIALIZED_DATA = true, |
| 2036 | .MEM_READ = true, | 2036 | .MEM_READ = true, |
| ... | @@ -2203,9 +2203,6 @@ pub fn initBuiltins(coff: *Coff) !void { | ... | @@ -2203,9 +2203,6 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2203 | ); | 2203 | ); |
| 2204 | | 2204 | |
| 2205 | const start_sym = start_osmi.symbol(coff).get(coff); | 2205 | 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 | | | |
| 2209 | try start_sym.ni.resize(&coff.mf, gpa, addr_info.size); | 2206 | try start_sym.ni.resize(&coff.mf, gpa, addr_info.size); |
| 2210 | const start_slice = start_sym.ni.slice(&coff.mf); | 2207 | const start_slice = start_sym.ni.slice(&coff.mf); |
| 2211 | switch (addr_info.magic) { | 2208 | switch (addr_info.magic) { |
| ... | @@ -2229,6 +2226,9 @@ pub fn initBuiltins(coff: *Coff) !void { | ... | @@ -2229,6 +2226,9 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2229 | const list_sym = list_si.get(coff); | 2226 | const list_sym = list_si.get(coff); |
| 2230 | list_sym.ni = start_sym.ni; | 2227 | list_sym.ni = start_sym.ni; |
| 2231 | list_sym.section_number = start_sym.section_number; | 2228 | 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; |
| 2232 | } | 2232 | } |
| 2233 | } | 2233 | } |
| 2234 | } | 2234 | } |
| ... | @@ -2564,7 +2564,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { | ... | @@ -2564,7 +2564,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2564 | .type = .unknown, | 2564 | .type = .unknown, |
| 2565 | .dll_storage_class = .default, | 2565 | .dll_storage_class = .default, |
| 2566 | .weak_external_strat = undefined, | 2566 | .weak_external_strat = undefined, |
| 2567 | .has_aliases = false, | 2567 | .has_alias = false, |
| 2568 | }, | 2568 | }, |
| 2569 | .loc_relocs = .none, | 2569 | .loc_relocs = .none, |
| 2570 | .target_relocs = .none, | 2570 | .target_relocs = .none, |
| ... | @@ -2692,10 +2692,6 @@ fn getDefinedGlobal(coff: *Coff, name: []const u8) Symbol.Index { | ... | @@ -2692,10 +2692,6 @@ fn getDefinedGlobal(coff: *Coff, name: []const u8) Symbol.Index { |
| 2692 | | 2692 | |
| 2693 | pub fn globalSymbol(coff: *Coff, opts: GlobalOptions) !Symbol.Index { | 2693 | pub fn globalSymbol(coff: *Coff, opts: GlobalOptions) !Symbol.Index { |
| 2694 | const gop = try coff.getOrPutGlobalSymbol(opts); | 2694 | 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 | | | |
| 2699 | return gop.value_ptr.*; | 2695 | return gop.value_ptr.*; |
| 2700 | } | 2696 | } |
| 2701 | | 2697 | |
| ... | @@ -3525,7 +3521,6 @@ pub fn addReloc( | ... | @@ -3525,7 +3521,6 @@ pub fn addReloc( |
| 3525 | ); | 3521 | ); |
| 3526 | | 3522 | |
| 3527 | // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?) | 3523 | // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?) |
| 3528 | | | |
| 3529 | const sri: Section.RelocationIndex = .wrap(old_num_relocations); | 3524 | const sri: Section.RelocationIndex = .wrap(old_num_relocations); |
| 3530 | const entry = sri.entry(coff, loc_sn).?; | 3525 | const entry = sri.entry(coff, loc_sn).?; |
| 3531 | if (sti.unwrap()) |index| coff.targetStore(&entry.symbol_table_index, index); | 3526 | if (sti.unwrap()) |index| coff.targetStore(&entry.symbol_table_index, index); |
| ... | @@ -3826,7 +3821,7 @@ fn loadObject( | ... | @@ -3826,7 +3821,7 @@ fn loadObject( |
| 3826 | try member.initHeader(coff, path_str, header.time_date_stamp); | 3821 | try member.initHeader(coff, path_str, header.time_date_stamp); |
| 3827 | | 3822 | |
| 3828 | { | 3823 | { |
| 3829 | // TODO: This could be deferred to an idle task? | 3824 | // TODO: This should be deferred to an idle task |
| 3830 | var nw: MappedFile.Node.Writer = undefined; | 3825 | var nw: MappedFile.Node.Writer = undefined; |
| 3831 | member.content_ni.writer(&coff.mf, gpa, &nw); | 3826 | member.content_ni.writer(&coff.mf, gpa, &nw); |
| 3832 | defer nw.deinit(); | 3827 | defer nw.deinit(); |
| ... | @@ -4101,7 +4096,7 @@ fn loadObject( | ... | @@ -4101,7 +4096,7 @@ fn loadObject( |
| 4101 | if (arg.len == 0) continue; | 4096 | if (arg.len == 0) continue; |
| 4102 | | 4097 | |
| 4103 | if (std.ascii.startsWithIgnoreCase(arg, "-exclude-symbols:")) { | 4098 | 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 |
| 4105 | } else if (std.ascii.startsWithIgnoreCase(arg, "/include:")) { | 4100 | } else if (std.ascii.startsWithIgnoreCase(arg, "/include:")) { |
| 4106 | _ = try coff.globalSymbol(.{ .name = arg["/include:".len..] }); | 4101 | _ = try coff.globalSymbol(.{ .name = arg["/include:".len..] }); |
| 4107 | } else if (std.ascii.startsWithIgnoreCase(arg, "/alternatename:")) { | 4102 | } else if (std.ascii.startsWithIgnoreCase(arg, "/alternatename:")) { |
| ... | @@ -4251,7 +4246,7 @@ fn loadObject( | ... | @@ -4251,7 +4246,7 @@ fn loadObject( |
| 4251 | .lib_name = null, | 4246 | .lib_name = null, |
| 4252 | }); | 4247 | }); |
| 4253 | | 4248 | |
| 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? |
| 4255 | // TODO: Would need to mark this global as pending, or notice it later when .ni != none | 4250 | // TODO: Would need to mark this global as pending, or notice it later when .ni != none |
| 4256 | if (!global_gop.found_existing or global_gop.value_ptr.get(coff).ni == .none) { | 4251 | if (!global_gop.found_existing or global_gop.value_ptr.get(coff).ni == .none) { |
| 4257 | symbol.si = global_gop.value_ptr.*; | 4252 | symbol.si = global_gop.value_ptr.*; |
| ... | @@ -4319,7 +4314,7 @@ fn loadObject( | ... | @@ -4319,7 +4314,7 @@ fn loadObject( |
| 4319 | .LARGEST => { | 4314 | .LARGEST => { |
| 4320 | // TODO: Resize existing .ni and replace with this section's contents | 4315 | // TODO: Resize existing .ni and replace with this section's contents |
| 4321 | // TODO: This will be tricky, what to do about existing InputSection? | 4316 | // TODO: This will be tricky, what to do about existing InputSection? |
| 4322 | unreachable; // TODO | 4317 | unreachable; |
| 4323 | }, | 4318 | }, |
| 4324 | .NONE, .ASSOCIATIVE, _ => unreachable, | 4319 | .NONE, .ASSOCIATIVE, _ => unreachable, |
| 4325 | } | 4320 | } |
| ... | @@ -4504,7 +4499,7 @@ fn loadObject( | ... | @@ -4504,7 +4499,7 @@ fn loadObject( |
| 4504 | symbol.si = coff.addSymbolAssumeCapacity(); | 4499 | symbol.si = coff.addSymbolAssumeCapacity(); |
| 4505 | }, | 4500 | }, |
| 4506 | .external => { | 4501 | .external => { |
| 4507 | // TODO: Assert this is not the comdat leader | 4502 | assert(index != section.comdat_psi.unwrap()); |
| 4508 | const global_gop = try coff.getOrPutGlobalSymbol(.{ .name = symbol.name.toSlice(coff) }); | 4503 | const global_gop = try coff.getOrPutGlobalSymbol(.{ .name = symbol.name.toSlice(coff) }); |
| 4509 | symbol.si = global_gop.value_ptr.*; | 4504 | symbol.si = global_gop.value_ptr.*; |
| 4510 | | 4505 | |
| ... | @@ -5017,7 +5012,7 @@ fn loadArchive(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !vo | ... | @@ -5017,7 +5012,7 @@ fn loadArchive(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !vo |
| 5017 | } else { | 5012 | } else { |
| 5018 | member.content.object.size = res.size; | 5013 | member.content.object.size = res.size; |
| 5019 | // TODO: If .UNKNOWN assert later that it contains no non-undef symbols? | 5014 | // 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 |
| 5021 | if (machine != expected_machine and machine != .UNKNOWN) { | 5016 | if (machine != expected_machine and machine != .UNKNOWN) { |
| 5022 | return diags.failParse(path, "machine mismatch in member header '{s}': expected {t}, found {t}", .{ | 5017 | return diags.failParse(path, "machine mismatch in member header '{s}': expected {t}, found {t}", .{ |
| 5023 | res.name, | 5018 | res.name, |
| ... | @@ -5192,7 +5187,6 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -5192,7 +5187,6 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5192 | si.applyLocationRelocs(coff); | 5187 | si.applyLocationRelocs(coff); |
| 5193 | } | 5188 | } |
| 5194 | | 5189 | |
| 5195 | // TODO: Did my MappedFile resize change affect this? | | |
| 5196 | if (nav.resolved.?.@"linksection".unwrap()) |_| { | 5190 | if (nav.resolved.?.@"linksection".unwrap()) |_| { |
| 5197 | try ni.resize(&coff.mf, gpa, si.get(coff).value.size); | 5191 | try ni.resize(&coff.mf, gpa, si.get(coff).value.size); |
| 5198 | var parent_ni = ni; | 5192 | var parent_ni = ni; |
| ... | @@ -5746,7 +5740,7 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -5746,7 +5740,7 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5746 | }; | 5740 | }; |
| 5747 | break :task; | 5741 | break :task; |
| 5748 | } | 5742 | } |
| 5749 | // TODO: Idle task for flushing obj into lib? | 5743 | // TODO: Idle task for flushing obj into lib |
| 5750 | if (coff.input_section_pending_index < coff.input_sections.items.len) { | 5744 | if (coff.input_section_pending_index < coff.input_sections.items.len) { |
| 5751 | const isi: Node.InputSection.Index = @enumFromInt(coff.input_section_pending_index); | 5745 | const isi: Node.InputSection.Index = @enumFromInt(coff.input_section_pending_index); |
| 5752 | coff.input_section_pending_index += 1; | 5746 | coff.input_section_pending_index += 1; |
| ... | @@ -7087,14 +7081,11 @@ fn updateExportsInner( | ... | @@ -7087,14 +7081,11 @@ fn updateExportsInner( |
| 7087 | Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu), | 7081 | Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu), |
| 7088 | ))), | 7082 | ))), |
| 7089 | }; | 7083 | }; |
| 7090 | while (try coff.idle(pt.tid)) {} // TODO: Is this necessary now that we handle exports moving via has_aliases? | | |
| 7091 | | 7084 | |
| 7092 | const machine = coff.targetLoad(&coff.headerPtr().machine); | 7085 | const machine = coff.targetLoad(&coff.headerPtr().machine); |
| 7093 | const exported_ni = exported_si.node(coff); | 7086 | const exported_ni = exported_si.node(coff); |
| 7094 | const exported_sym = exported_si.get(coff); | 7087 | const exported_sym = exported_si.get(coff); |
| 7095 | exported_sym.extra = .{ .first_alias_si = @enumFromInt(coff.symbols.items.len) }; | 7088 | var prev_alias_si = exported_si; |
| 7096 | exported_sym.flags.has_aliases = true; | | |
| 7097 | | | |
| 7098 | for (export_indices) |export_index| { | 7089 | for (export_indices) |export_index| { |
| 7099 | const @"export" = export_index.ptr(zcu); | 7090 | const @"export" = export_index.ptr(zcu); |
| 7100 | const name = @"export".opts.name.toSlice(ip); | 7091 | const name = @"export".opts.name.toSlice(ip); |
| ... | @@ -7111,6 +7102,12 @@ fn updateExportsInner( | ... | @@ -7111,6 +7102,12 @@ fn updateExportsInner( |
| 7111 | export_sym.section_number = exported_sym.section_number; | 7102 | export_sym.section_number = exported_sym.section_number; |
| 7112 | defer export_si.applyTargetRelocs(coff, .none); | 7103 | defer export_si.applyTargetRelocs(coff, .none); |
| 7113 | | 7104 | |
| | 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 | |
| 7114 | if (!coff.isImage()) continue; | 7111 | if (!coff.isImage()) continue; |
| 7115 | | 7112 | |
| 7116 | const entries_ctx = ExportTable.Adapter{ .coff = coff }; | 7113 | const entries_ctx = ExportTable.Adapter{ .coff = coff }; |
| ... | @@ -7153,7 +7150,8 @@ fn updateExportsInner( | ... | @@ -7153,7 +7150,8 @@ fn updateExportsInner( |
| 7153 | coff.targetStore(&edt.number_of_names, @intCast(export_count)); | 7150 | coff.targetStore(&edt.number_of_names, @intCast(export_count)); |
| 7154 | edt.number_of_entries = edt.number_of_names; | 7151 | edt.number_of_entries = edt.number_of_names; |
| 7155 | | 7152 | |
| 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 |
| 7157 | try coff.export_table.export_address_table_si.node(coff).resize( | 7155 | try coff.export_table.export_address_table_si.node(coff).resize( |
| 7158 | &coff.mf, | 7156 | &coff.mf, |
| 7159 | gpa, | 7157 | gpa, |