| ... | ... | @@ -49,6 +49,7 @@ input_sections: std.ArrayList(Node.InputSection), |
| 49 | 49 | input_section_pending_index: u32, |
| 50 | 50 | inputs_complete: bool, |
| 51 | 51 | exports_complete: bool, |
| 52 | special_symbols_complete: bool, |
| 52 | 53 | strings: std.HashMapUnmanaged( |
| 53 | 54 | u32, |
| 54 | 55 | void, |
| ... | ... | @@ -74,7 +75,6 @@ pending_uavs: std.array_hash_map.Auto(Node.UavMapIndex, struct { |
| 74 | 75 | alignment: InternPool.Alignment, |
| 75 | 76 | }), |
| 76 | 77 | relocs: std.ArrayList(Reloc), |
| 77 | | entry: Node.GlobalMapIndex, |
| 78 | 78 | const_prog_node: std.Progress.Node, |
| 79 | 79 | synth_prog_node: std.Progress.Node, |
| 80 | 80 | symbol_prog_node: std.Progress.Node, |
| ... | ... | @@ -896,8 +896,7 @@ pub const Symbol = struct { |
| 896 | 896 | dll_storage_class: DllStorageClass, |
| 897 | 897 | // Only defined for .alias_si and .alias_name |
| 898 | 898 | weak_external_strat: WeakExternalStrat, |
| 899 | | is_entry: bool, |
| 900 | | _: u7 = 0, |
| 899 | _: u8 = 0, |
| 901 | 900 | }, |
| 902 | 901 | /// Relocations contained within this symbol |
| 903 | 902 | loc_relocs: Reloc.Index, |
| ... | ... | @@ -1017,6 +1016,11 @@ pub const Symbol = struct { |
| 1017 | 1016 | return &coff.symbols.items[@intFromEnum(si)]; |
| 1018 | 1017 | } |
| 1019 | 1018 | |
| 1019 | pub fn unwrap(si: Symbol.Index) ?Symbol.Index { |
| 1020 | if (si == .null) return null; |
| 1021 | return si; |
| 1022 | } |
| 1023 | |
| 1020 | 1024 | pub fn node(si: Symbol.Index, coff: *Coff) MappedFile.Node.Index { |
| 1021 | 1025 | const ni = si.get(coff).ni; |
| 1022 | 1026 | assert(ni != .none); |
| ... | ... | @@ -1074,12 +1078,6 @@ pub const Symbol = struct { |
| 1074 | 1078 | pub fn applyTargetRelocs(si: Symbol.Index, coff: *Coff, end: Reloc.Index) void { |
| 1075 | 1079 | const sym = si.get(coff); |
| 1076 | 1080 | |
| 1077 | | // TODO: Would this be better modeled using an actual reloc? Would need a si for the header |
| 1078 | | if (sym.flags.is_entry) { |
| 1079 | | log.debug("updateEntryRVA({d}, 0x{x})", .{ si, sym.rva }); |
| 1080 | | coff.optionalHeaderStandardPtr().address_of_entry_point = sym.rva; |
| 1081 | | } |
| 1082 | | |
| 1083 | 1081 | var ri = sym.target_relocs; |
| 1084 | 1082 | while (ri != end) { |
| 1085 | 1083 | const reloc = ri.get(coff); |
| ... | ... | @@ -1549,6 +1547,7 @@ fn create( |
| 1549 | 1547 | .input_section_pending_index = 0, |
| 1550 | 1548 | .inputs_complete = false, |
| 1551 | 1549 | .exports_complete = false, |
| 1550 | .special_symbols_complete = false, |
| 1552 | 1551 | .strings = .empty, |
| 1553 | 1552 | .string_bytes = .empty, |
| 1554 | 1553 | .section_table = .empty, |
| ... | ... | @@ -1567,7 +1566,6 @@ fn create( |
| 1567 | 1566 | }), |
| 1568 | 1567 | .pending_uavs = .empty, |
| 1569 | 1568 | .relocs = .empty, |
| 1570 | | .entry = .none, |
| 1571 | 1569 | .const_prog_node = .none, |
| 1572 | 1570 | .synth_prog_node = .none, |
| 1573 | 1571 | .symbol_prog_node = .none, |
| ... | ... | @@ -2525,7 +2523,6 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2525 | 2523 | .type = .unknown, |
| 2526 | 2524 | .dll_storage_class = .default, |
| 2527 | 2525 | .weak_external_strat = undefined, |
| 2528 | | .is_entry = false, |
| 2529 | 2526 | }, |
| 2530 | 2527 | .loc_relocs = .none, |
| 2531 | 2528 | .target_relocs = .none, |
| ... | ... | @@ -2642,6 +2639,14 @@ fn getOrPutGlobalSymbol( |
| 2642 | 2639 | return sym_gop; |
| 2643 | 2640 | } |
| 2644 | 2641 | |
| 2642 | fn getDefinedGlobal(coff: *Coff, name: []const u8) Symbol.Index { |
| 2643 | if (coff.globals.get(.{ |
| 2644 | .name = coff.getString(name).unwrap() orelse return .null, |
| 2645 | .lib_name = .none, |
| 2646 | })) |si| if (si.get(coff).ni != .none) return si; |
| 2647 | return .null; |
| 2648 | } |
| 2649 | |
| 2645 | 2650 | pub fn globalSymbol(coff: *Coff, opts: GlobalOptions) !Symbol.Index { |
| 2646 | 2651 | const gop = try coff.getOrPutGlobalSymbol(opts); |
| 2647 | 2652 | if (gop.found_existing) { |
| ... | ... | @@ -3423,8 +3428,6 @@ pub fn addReloc( |
| 3423 | 3428 | ) !void { |
| 3424 | 3429 | const gpa = coff.base.comp.gpa; |
| 3425 | 3430 | const target = target_si.get(coff); |
| 3426 | | // TODO: Could duplicate the uninit flag on Symbol.flags? |
| 3427 | | assert(!coff.targetLoad(loc_si.get(coff).section_number.header(coff).flags).CNT_UNINITIALIZED_DATA); |
| 3428 | 3431 | |
| 3429 | 3432 | const ri: Reloc.Index = @enumFromInt(coff.relocs.items.len); |
| 3430 | 3433 | log.debug("addReloc({d}@{d}+0x{x} -> {d}@{d}+0x{x}{s}) = {d}", .{ |
| ... | ... | @@ -4386,11 +4389,10 @@ fn loadObject( |
| 4386 | 4389 | // Resolve this once we see alias |
| 4387 | 4390 | alias.weak_external_psi = .wrap(@intCast(i)); |
| 4388 | 4391 | } else { |
| 4389 | | sym.setValue(if (alias.si == .null) .{ |
| 4390 | | // See .external branch above |
| 4391 | | .alias_name = alias.name, |
| 4392 | sym.setValue(if (alias.si.unwrap()) |alias_si| .{ |
| 4393 | .alias_si = alias_si, |
| 4392 | 4394 | } else .{ |
| 4393 | | .alias_si = alias.si, |
| 4395 | .alias_name = alias.name, |
| 4394 | 4396 | }); |
| 4395 | 4397 | sym.flags.weak_external_strat = pending_symbols.values()[i + 1].value.weak_external_aux; |
| 4396 | 4398 | } |
| ... | ... | @@ -5027,35 +5029,9 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { |
| 5027 | 5029 | } |
| 5028 | 5030 | } |
| 5029 | 5031 | |
| 5030 | | if (coff.isImage() and comp.config.link_libc) { |
| 5031 | | const entries: []const struct { ?[]const u8, []const u8 } = if (coff.isExe()) |
| 5032 | | if (comp.zcu == null) switch (coff.optionalHeaderField(.subsystem)) { |
| 5033 | | .WINDOWS_CUI => &.{ |
| 5034 | | .{ "main", "mainCRTStartup" }, |
| 5035 | | .{ "wmain", "wmainCRTStartup" }, |
| 5036 | | }, |
| 5037 | | .WINDOWS_GUI => &.{ |
| 5038 | | .{ "WinMain", "WinMainCRTStartup" }, |
| 5039 | | .{ "wWinMain", "wWinMainCRTStartup" }, |
| 5040 | | }, |
| 5041 | | else => unreachable, |
| 5042 | | } else &.{} |
| 5043 | | else |
| 5044 | | &.{.{ null, "_DllMainCRTStartup" }}; |
| 5045 | | |
| 5046 | | for (entries) |entry| { |
| 5047 | | if (entry[0]) |required_name| { |
| 5048 | | const str = coff.getString(required_name).unwrap() orelse continue; |
| 5049 | | const si = coff.globals.get(.{ .name = str, .lib_name = .none }) orelse continue; |
| 5050 | | if (si.get(coff).ni == .none) continue; |
| 5051 | | } |
| 5052 | | |
| 5053 | | const si = try coff.globalSymbol(.{ .name = entry[1], .type = .code }); |
| 5054 | | coff.updateEntry(si.get(coff).gmi); |
| 5055 | | } |
| 5056 | | } |
| 5057 | | |
| 5058 | 5032 | coff.inputs_complete = true; |
| 5033 | if (comp.zcu == null) |
| 5034 | coff.exports_complete = true; |
| 5059 | 5035 | } |
| 5060 | 5036 | |
| 5061 | 5037 | pub fn updateNav(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| ... | ... | @@ -5347,17 +5323,6 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5347 | 5323 | const gpa = comp.gpa; |
| 5348 | 5324 | const max_notes = 4; |
| 5349 | 5325 | |
| 5350 | | if (coff.isImage()) { |
| 5351 | | if (coff.entry == .none) |
| 5352 | | comp.link_diags.addError("no entry point defined", .{}) |
| 5353 | | else if (coff.entry.symbol(coff).get(coff).ni == .none) { |
| 5354 | | comp.link_diags.addError( |
| 5355 | | "no definition for entry point '{s}' found", |
| 5356 | | .{coff.entry.globalName(coff).name.toSlice(coff)}, |
| 5357 | | ); |
| 5358 | | } |
| 5359 | | } |
| 5360 | | |
| 5361 | 5326 | var undef_indices: std.ArrayListUnmanaged(u32) = .empty; |
| 5362 | 5327 | for (coff.relocs.items, 0..) |reloc, reloc_i| { |
| 5363 | 5328 | const target_sym = reloc.target.get(coff); |
| ... | ... | @@ -5406,12 +5371,20 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5406 | 5371 | for (undef_indices.items[start_i .. i + 1]) |reference_i| { |
| 5407 | 5372 | if (err.note_slot == num_full_notes) break; |
| 5408 | 5373 | |
| 5409 | | const loc_si = coff.relocs.items[reference_i].loc; |
| 5374 | const reloc = &coff.relocs.items[reference_i]; |
| 5375 | const loc_si = reloc.loc; |
| 5410 | 5376 | if (loc_si == prev_loc_si) continue; |
| 5411 | 5377 | defer prev_loc_si = loc_si; |
| 5412 | 5378 | |
| 5413 | 5379 | const loc_sym = loc_si.get(coff); |
| 5414 | 5380 | switch (coff.getNode(loc_sym.ni)) { |
| 5381 | .data_directories => { |
| 5382 | const dir_align = std.mem.Alignment.of(std.coff.ImageDataDirectory); |
| 5383 | const dir: std.coff.IMAGE.DIRECTORY_ENTRY = |
| 5384 | @enumFromInt(dir_align.backward(reloc.offset) / @sizeOf(std.coff.IMAGE.DIRECTORY_ENTRY)); |
| 5385 | err.addNote("referenced by data directory entry: {t}", .{dir}); |
| 5386 | }, |
| 5387 | .optional_header => err.addNote("referenced by optional header field", .{}), |
| 5415 | 5388 | .input_section => |isi| { |
| 5416 | 5389 | const other_ioi = isi.input(coff); |
| 5417 | 5390 | if (loc_sym.gmi == .none) { |
| ... | ... | @@ -5577,6 +5550,17 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5577 | 5550 | }) coff.late_globals_pending_index += 1; |
| 5578 | 5551 | break :task; |
| 5579 | 5552 | } |
| 5553 | if (coff.exports_complete and !coff.special_symbols_complete) { |
| 5554 | coff.special_symbols_complete = true; |
| 5555 | coff.flushSpecialSymbols() catch |err| switch (err) { |
| 5556 | error.OutOfMemory => |e| return e, |
| 5557 | else => |e| return comp.link_diags.fail( |
| 5558 | "linker failed to flush special symbols: {t}", |
| 5559 | .{e}, |
| 5560 | ), |
| 5561 | }; |
| 5562 | break :task; |
| 5563 | } |
| 5580 | 5564 | var lazy_it = coff.lazy.iterator(); |
| 5581 | 5565 | while (lazy_it.next()) |lazy| if (lazy.value.pending_index < lazy.value.map.count()) { |
| 5582 | 5566 | const pt: Zcu.PerThread = .{ .zcu = comp.zcu.?, .tid = tid }; |
| ... | ... | @@ -5713,7 +5697,9 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5713 | 5697 | if (coff.pending_uavs.count() > 0) return true; |
| 5714 | 5698 | if (coff.pending_input != null) return true; |
| 5715 | 5699 | if (coff.inputs_complete and coff.globals.count() > coff.global_pending_index) return true; |
| 5700 | assert(!coff.exports_complete or coff.inputs_complete); |
| 5716 | 5701 | if (coff.exports_complete and coff.late_globals.items.len > coff.late_globals_pending_index) return true; |
| 5702 | if (coff.exports_complete and !coff.special_symbols_complete) return true; |
| 5717 | 5703 | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; |
| 5718 | 5704 | if (coff.symbol_table.pending.count() > 0) return true; |
| 5719 | 5705 | if (coff.input_sections.items.len > coff.input_section_pending_index) return true; |
| ... | ... | @@ -6258,6 +6244,105 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6258 | 6244 | return true; |
| 6259 | 6245 | } |
| 6260 | 6246 | |
| 6247 | fn flushSpecialSymbols(coff: *Coff) !void { |
| 6248 | const comp = coff.base.comp; |
| 6249 | const gpa = comp.gpa; |
| 6250 | const machine = coff.targetLoad(&coff.headerPtr().machine); |
| 6251 | |
| 6252 | if (coff.isImage()) { |
| 6253 | // TODO: Use explicitly specified entry if set, add err if not found |
| 6254 | const entries: []const struct { ?[]const u8, []const u8 } = if (coff.isExe()) |
| 6255 | if (comp.config.link_libc) switch (coff.optionalHeaderField(.subsystem)) { |
| 6256 | .WINDOWS_CUI => &.{ |
| 6257 | .{ "main", "mainCRTStartup" }, |
| 6258 | .{ "wmain", "wmainCRTStartup" }, |
| 6259 | }, |
| 6260 | .WINDOWS_GUI => &.{ |
| 6261 | .{ "WinMain", "WinMainCRTStartup" }, |
| 6262 | .{ "wWinMain", "wWinMainCRTStartup" }, |
| 6263 | }, |
| 6264 | else => unreachable, |
| 6265 | } else &.{ |
| 6266 | .{ "wWinMainCRTStartup", "wWinMainCRTStartup" }, |
| 6267 | } |
| 6268 | else |
| 6269 | &.{.{ null, "_DllMainCRTStartup" }}; |
| 6270 | |
| 6271 | const entry_si = for (entries) |entry| { |
| 6272 | if (entry[0]) |required_name| |
| 6273 | if (coff.getDefinedGlobal(required_name) == .null) continue; |
| 6274 | |
| 6275 | break try coff.globalSymbol(.{ .name = entry[1], .type = .code }); |
| 6276 | } else .null; |
| 6277 | |
| 6278 | if (entry_si != .null) { |
| 6279 | log.debug( |
| 6280 | "entry({s}, {d})", |
| 6281 | .{ entry_si.get(coff).gmi.globalName(coff).name.toSlice(coff), entry_si }, |
| 6282 | ); |
| 6283 | |
| 6284 | try coff.symbols.ensureTotalCapacity(gpa, 1); |
| 6285 | const optional_hdr_si = coff.addSymbolAssumeCapacity(); |
| 6286 | const optional_hdr_sym = optional_hdr_si.get(coff); |
| 6287 | optional_hdr_sym.ni = Node.known.optional_header; |
| 6288 | assert(optional_hdr_sym.loc_relocs == .none); |
| 6289 | optional_hdr_sym.loc_relocs = @enumFromInt(coff.relocs.items.len); |
| 6290 | |
| 6291 | const optional_hdr = coff.optionalHeaderStandardPtr(); |
| 6292 | optional_hdr.address_of_entry_point = std.mem.nativeTo( |
| 6293 | u32, |
| 6294 | entry_si.get(coff).rva, |
| 6295 | coff.targetEndian(), |
| 6296 | ); |
| 6297 | |
| 6298 | try coff.addReloc( |
| 6299 | optional_hdr_si, |
| 6300 | @intFromPtr(&optional_hdr.address_of_entry_point) - @intFromPtr(optional_hdr), |
| 6301 | entry_si, |
| 6302 | .{ .known = 0 }, |
| 6303 | switch (machine) { |
| 6304 | else => |tag| @panic(@tagName(tag)), |
| 6305 | .AMD64 => .{ .AMD64 = .ADDR32NB }, |
| 6306 | .I386 => .{ .I386 = .DIR32NB }, |
| 6307 | }, |
| 6308 | ); |
| 6309 | } |
| 6310 | } |
| 6311 | |
| 6312 | if (coff.getDefinedGlobal("_tls_used").unwrap()) |tls_used_si| { |
| 6313 | const tls_directory = coff.dataDirectoryPtr(.TLS); |
| 6314 | tls_directory.* = .{ |
| 6315 | .virtual_address = tls_used_si.get(coff).rva, |
| 6316 | .size = switch (coff.targetLoad(&coff.optionalHeaderStandardPtr().magic)) { |
| 6317 | _ => unreachable, |
| 6318 | .PE32 => 24, |
| 6319 | .@"PE32+" => 40, |
| 6320 | }, |
| 6321 | }; |
| 6322 | if (coff.targetEndian() != native_endian) |
| 6323 | std.mem.byteSwapAllFields(std.coff.ImageDataDirectory, tls_directory); |
| 6324 | |
| 6325 | try coff.symbols.ensureTotalCapacity(gpa, 1); |
| 6326 | const data_dir_si = coff.addSymbolAssumeCapacity(); |
| 6327 | const data_dir_sym = data_dir_si.get(coff); |
| 6328 | data_dir_sym.ni = Node.known.data_directories; |
| 6329 | assert(data_dir_sym.loc_relocs == .none); |
| 6330 | data_dir_sym.loc_relocs = @enumFromInt(coff.relocs.items.len); |
| 6331 | |
| 6332 | try coff.addReloc( |
| 6333 | data_dir_si, |
| 6334 | @intFromPtr(&tls_directory.virtual_address) - @intFromPtr(coff.dataDirectorySlice().ptr), |
| 6335 | tls_used_si, |
| 6336 | .{ .known = 0 }, |
| 6337 | switch (machine) { |
| 6338 | else => |tag| @panic(@tagName(tag)), |
| 6339 | .AMD64 => .{ .AMD64 = .ADDR32NB }, |
| 6340 | .I386 => .{ .I386 = .DIR32NB }, |
| 6341 | }, |
| 6342 | ); |
| 6343 | } |
| 6344 | } |
| 6345 | |
| 6261 | 6346 | fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6262 | 6347 | const zcu = pt.zcu; |
| 6263 | 6348 | const gpa = zcu.gpa; |
| ... | ... | @@ -6312,7 +6397,7 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6312 | 6397 | } |
| 6313 | 6398 | |
| 6314 | 6399 | fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6315 | | log.debug("flushMoved({s})", .{@tagName(coff.getNode(ni))}); |
| 6400 | log.debug("flushMoved({s}, n{d})", .{ @tagName(coff.getNode(ni)), ni }); |
| 6316 | 6401 | switch (coff.getNode(ni)) { |
| 6317 | 6402 | .file, |
| 6318 | 6403 | .header, |
| ... | ... | @@ -6500,7 +6585,7 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6500 | 6585 | |
| 6501 | 6586 | fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6502 | 6587 | const offset, const size = ni.location(&coff.mf).resolve(&coff.mf); |
| 6503 | | log.debug("flushResized({s}, 0x{x})", .{ @tagName(coff.getNode(ni)), size }); |
| 6588 | log.debug("flushResized({s}, n{d}, 0x{x})", .{ @tagName(coff.getNode(ni)), ni, size }); |
| 6504 | 6589 | |
| 6505 | 6590 | switch (coff.getNode(ni)) { |
| 6506 | 6591 | .file => { |
| ... | ... | @@ -6779,6 +6864,7 @@ fn updateExportsInner( |
| 6779 | 6864 | }; |
| 6780 | 6865 | while (try coff.idle(pt.tid)) {} |
| 6781 | 6866 | |
| 6867 | const machine = coff.targetLoad(&coff.headerPtr().machine); |
| 6782 | 6868 | const exported_ni = exported_si.node(coff); |
| 6783 | 6869 | const exported_sym = exported_si.get(coff); |
| 6784 | 6870 | for (export_indices) |export_index| { |
| ... | ... | @@ -6795,18 +6881,7 @@ fn updateExportsInner( |
| 6795 | 6881 | export_sym.section_number = exported_sym.section_number; |
| 6796 | 6882 | defer export_si.applyTargetRelocs(coff, .none); |
| 6797 | 6883 | |
| 6798 | | if (coff.isImage()) { |
| 6799 | | if (@"export".opts.name.eqlSlice("_tls_used", ip)) { |
| 6800 | | const tls_directory = coff.dataDirectoryPtr(.TLS); |
| 6801 | | tls_directory.* = .{ .virtual_address = exported_sym.rva, .size = exported_sym.value.size }; |
| 6802 | | if (coff.targetEndian() != native_endian) |
| 6803 | | std.mem.byteSwapAllFields(std.coff.ImageDataDirectory, tls_directory); |
| 6804 | | } else if ((coff.isExe() and @"export".opts.name.eqlSlice("wWinMainCRTStartup", ip)) or |
| 6805 | | (!coff.isExe() and @"export".opts.name.eqlSlice("_DllMainCRTStartup", ip))) |
| 6806 | | { |
| 6807 | | coff.updateEntry(export_sym.gmi); |
| 6808 | | } |
| 6809 | | } else continue; |
| 6884 | if (!coff.isImage()) continue; |
| 6810 | 6885 | |
| 6811 | 6886 | const entries_ctx = ExportTable.Adapter{ .coff = coff }; |
| 6812 | 6887 | const gop = try coff.export_table.entries.getOrPutAdapted( |
| ... | ... | @@ -6888,7 +6963,11 @@ fn updateExportsInner( |
| 6888 | 6963 | @intCast(@sizeOf(std.coff.ExportAddressTableEntry) * gop.index), |
| 6889 | 6964 | export_si, |
| 6890 | 6965 | .{ .known = 0 }, |
| 6891 | | .{ .AMD64 = .ADDR32NB }, |
| 6966 | switch (machine) { |
| 6967 | else => |tag| @panic(@tagName(tag)), |
| 6968 | .AMD64 => .{ .AMD64 = .ADDR32NB }, |
| 6969 | .I386 => .{ .I386 = .DIR32NB }, |
| 6970 | }, |
| 6892 | 6971 | ); |
| 6893 | 6972 | } else { |
| 6894 | 6973 | gop.value_ptr.si = export_si; |
| ... | ... | @@ -6898,20 +6977,6 @@ fn updateExportsInner( |
| 6898 | 6977 | } |
| 6899 | 6978 | } |
| 6900 | 6979 | |
| 6901 | | /// Caller ensures that `applyTargetRelocs` will be called on `si` eventually |
| 6902 | | fn updateEntry(coff: *Coff, gmi: Node.GlobalMapIndex) void { |
| 6903 | | const si = gmi.symbol(coff); |
| 6904 | | log.debug("updateEntry({s}, {d})", .{ gmi.globalName(coff).name.toSlice(coff), si }); |
| 6905 | | |
| 6906 | | if (coff.entry != .none) |
| 6907 | | coff.entry.symbol(coff).get(coff).flags.is_entry = false; |
| 6908 | | |
| 6909 | | // TODO: Should we detect the subsystem like link.exe does (if not explicitly set) based on entry name? |
| 6910 | | |
| 6911 | | coff.entry = gmi; |
| 6912 | | si.get(coff).flags.is_entry = true; |
| 6913 | | } |
| 6914 | | |
| 6915 | 6980 | pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTerminatedString) void { |
| 6916 | 6981 | _ = coff; |
| 6917 | 6982 | _ = exported; |
| ... | ... | @@ -6928,11 +6993,15 @@ fn dumpStderr(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 6928 | 6993 | const stderr = try io.lockStderr(&buffer, null); |
| 6929 | 6994 | defer io.unlockStderr(); |
| 6930 | 6995 | const w = &stderr.file_writer.interface; |
| 6931 | | try coff.dump(w, tid); |
| 6996 | _ = try coff.dump(w, tid); |
| 6932 | 6997 | } |
| 6933 | 6998 | |
| 6934 | | pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !void { |
| 6935 | | try coff.printNode(tid, w, .root, 0); |
| 6999 | pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult { |
| 7000 | if (coff.dump_snapshot) { |
| 7001 | try coff.printNode(tid, w, .root, 0); |
| 7002 | return .enabled; |
| 7003 | } |
| 7004 | return .disabled; |
| 6936 | 7005 | } |
| 6937 | 7006 | |
| 6938 | 7007 | pub fn printNode( |