| ... | ... | @@ -74,12 +74,12 @@ pending_uavs: std.array_hash_map.Auto(Node.UavMapIndex, struct { |
| 74 | 74 | alignment: InternPool.Alignment, |
| 75 | 75 | }), |
| 76 | 76 | relocs: std.ArrayList(Reloc), |
| 77 | entry: Node.GlobalMapIndex, |
| 77 | 78 | const_prog_node: std.Progress.Node, |
| 78 | 79 | synth_prog_node: std.Progress.Node, |
| 79 | 80 | symbol_prog_node: std.Progress.Node, |
| 80 | 81 | member_prog_node: std.Progress.Node, |
| 81 | 82 | input_prog_node: std.Progress.Node, |
| 82 | | subsystem: ?std.zig.Subsystem, |
| 83 | 83 | dump_snapshot: bool, |
| 84 | 84 | |
| 85 | 85 | pub const default_file_alignment: u16 = 0x200; |
| ... | ... | @@ -728,10 +728,37 @@ pub const ImportTable = struct { |
| 728 | 728 | import_lookup_table_ni: MappedFile.Node.Index, |
| 729 | 729 | import_address_table_si: Symbol.Index, |
| 730 | 730 | import_hint_name_table_ni: MappedFile.Node.Index, |
| 731 | // All .iat_ptr globals that reference this table. |
| 732 | // This is separate from `iat_symbol_indices` because multiple symbols |
| 733 | // can reference to the same iat entry, after name demangling. |
| 734 | import_address_table_symbols: std.ArrayList(Symbol.Index), |
| 731 | 735 | len: u32, |
| 732 | 736 | hint_name_len: u32, |
| 733 | 737 | }; |
| 734 | 738 | |
| 739 | pub fn TableEntry(comptime magic: std.coff.OptionalHeader.Magic) type { |
| 740 | const Payload = packed union(u31) { |
| 741 | ordinal: packed struct(u31) { |
| 742 | ordinal: u16, |
| 743 | _: u15 = 0, |
| 744 | }, |
| 745 | hint_name_rva: u31, |
| 746 | }; |
| 747 | |
| 748 | return switch (magic) { |
| 749 | _ => comptime unreachable, |
| 750 | .PE32 => packed struct(u32) { |
| 751 | payload: Payload, |
| 752 | is_ordinal: bool, |
| 753 | }, |
| 754 | .@"PE32+" => packed struct(u64) { |
| 755 | payload: Payload, |
| 756 | _: u32 = 0, |
| 757 | is_ordinal: bool, |
| 758 | }, |
| 759 | }; |
| 760 | } |
| 761 | |
| 735 | 762 | const Adapter = struct { |
| 736 | 763 | coff: *Coff, |
| 737 | 764 | |
| ... | ... | @@ -864,7 +891,8 @@ pub const Symbol = struct { |
| 864 | 891 | dll_storage_class: DllStorageClass, |
| 865 | 892 | // Only defined for .alias_si and .alias_name |
| 866 | 893 | weak_external_strat: WeakExternalStrat, |
| 867 | | _: u8 = 0, |
| 894 | is_entry: bool, |
| 895 | _: u7 = 0, |
| 868 | 896 | }, |
| 869 | 897 | /// Relocations contained within this symbol |
| 870 | 898 | loc_relocs: Reloc.Index, |
| ... | ... | @@ -1038,7 +1066,15 @@ pub const Symbol = struct { |
| 1038 | 1066 | } |
| 1039 | 1067 | |
| 1040 | 1068 | pub fn applyTargetRelocs(si: Symbol.Index, coff: *Coff) void { |
| 1041 | | var ri = si.get(coff).target_relocs; |
| 1069 | const sym = si.get(coff); |
| 1070 | |
| 1071 | // TODO: Would this be better modeled using an actual reloc? Would need a si for the header |
| 1072 | if (sym.flags.is_entry) { |
| 1073 | log.debug("updateEntryRVA({d}, 0x{x})", .{ si, sym.rva }); |
| 1074 | coff.optionalHeaderStandardPtr().address_of_entry_point = sym.rva; |
| 1075 | } |
| 1076 | |
| 1077 | var ri = sym.target_relocs; |
| 1042 | 1078 | while (ri != .none) { |
| 1043 | 1079 | const reloc = ri.get(coff); |
| 1044 | 1080 | assert(reloc.target == si); |
| ... | ... | @@ -1525,12 +1561,12 @@ fn create( |
| 1525 | 1561 | }), |
| 1526 | 1562 | .pending_uavs = .empty, |
| 1527 | 1563 | .relocs = .empty, |
| 1564 | .entry = .none, |
| 1528 | 1565 | .const_prog_node = .none, |
| 1529 | 1566 | .synth_prog_node = .none, |
| 1530 | 1567 | .symbol_prog_node = .none, |
| 1531 | 1568 | .member_prog_node = .none, |
| 1532 | 1569 | .input_prog_node = .none, |
| 1533 | | .subsystem = options.subsystem, |
| 1534 | 1570 | .dump_snapshot = options.enable_link_snapshots, |
| 1535 | 1571 | }; |
| 1536 | 1572 | errdefer coff.deinit(); |
| ... | ... | @@ -1549,6 +1585,11 @@ fn create( |
| 1549 | 1585 | major_subsystem_version, |
| 1550 | 1586 | minor_subsystem_version, |
| 1551 | 1587 | magic, |
| 1588 | if (options.subsystem) |s| switch (s) { |
| 1589 | .console => .WINDOWS_CUI, |
| 1590 | .windows => .WINDOWS_GUI, |
| 1591 | else => return error.UnsupportedCOFFSubsystem, |
| 1592 | } else .WINDOWS_CUI, |
| 1552 | 1593 | section_align, |
| 1553 | 1594 | std.fs.path.basename(path.sub_path), |
| 1554 | 1595 | ); |
| ... | ... | @@ -1619,6 +1660,10 @@ fn isArchive(coff: *const Coff) bool { |
| 1619 | 1660 | }; |
| 1620 | 1661 | } |
| 1621 | 1662 | |
| 1663 | fn isExe(coff: *const Coff) bool { |
| 1664 | return coff.base.comp.config.output_mode == .Exe; |
| 1665 | } |
| 1666 | |
| 1622 | 1667 | fn isObj(coff: *const Coff) bool { |
| 1623 | 1668 | return coff.base.comp.config.output_mode == .Obj; |
| 1624 | 1669 | } |
| ... | ... | @@ -1639,6 +1684,7 @@ fn initHeaders( |
| 1639 | 1684 | major_subsystem_version: u16, |
| 1640 | 1685 | minor_subsystem_version: u16, |
| 1641 | 1686 | magic: std.coff.OptionalHeader.Magic, |
| 1687 | subsystem: std.coff.Subsystem, |
| 1642 | 1688 | section_align: std.mem.Alignment, |
| 1643 | 1689 | file_name: []const u8, |
| 1644 | 1690 | ) !void { |
| ... | ... | @@ -1841,7 +1887,7 @@ fn initHeaders( |
| 1841 | 1887 | .size_of_image = 0, |
| 1842 | 1888 | .size_of_headers = 0, |
| 1843 | 1889 | .checksum = 0, |
| 1844 | | .subsystem = .WINDOWS_CUI, |
| 1890 | .subsystem = subsystem, |
| 1845 | 1891 | .dll_flags = .{ |
| 1846 | 1892 | .HIGH_ENTROPY_VA = true, |
| 1847 | 1893 | .DYNAMIC_BASE = true, |
| ... | ... | @@ -1890,7 +1936,7 @@ fn initHeaders( |
| 1890 | 1936 | .size_of_image = 0, |
| 1891 | 1937 | .size_of_headers = 0, |
| 1892 | 1938 | .checksum = 0, |
| 1893 | | .subsystem = .WINDOWS_CUI, |
| 1939 | .subsystem = subsystem, |
| 1894 | 1940 | .dll_flags = .{ |
| 1895 | 1941 | .HIGH_ENTROPY_VA = true, |
| 1896 | 1942 | .DYNAMIC_BASE = true, |
| ... | ... | @@ -2079,9 +2125,6 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2079 | 2125 | const gpa = comp.gpa; |
| 2080 | 2126 | const target = &comp.root_mod.resolved_target.result; |
| 2081 | 2127 | if (coff.isImage()) { |
| 2082 | | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 2083 | | try coff.globals.ensureUnusedCapacity(gpa, 1); |
| 2084 | | |
| 2085 | 2128 | const si = try coff.globalSymbol(.{ .name = "__ImageBase", .type = .data }); |
| 2086 | 2129 | const sym = si.get(coff); |
| 2087 | 2130 | sym.ni = Node.known.header; |
| ... | ... | @@ -2099,8 +2142,16 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2099 | 2142 | |
| 2100 | 2143 | for (lists) |list| { |
| 2101 | 2144 | const addr_info = coff.targetAddrInfo(); |
| 2102 | | const start_osmi = try coff.objectSectionMapIndex(list.start, addr_info.alignment, .{ .read = true }); |
| 2103 | | const end_osmi = try coff.objectSectionMapIndex(list.end, addr_info.alignment, .{ .read = true }); |
| 2145 | const start_osmi = try coff.objectSectionMapIndex( |
| 2146 | list.start, |
| 2147 | addr_info.alignment, |
| 2148 | .{ .read = true }, |
| 2149 | ); |
| 2150 | const end_osmi = try coff.objectSectionMapIndex( |
| 2151 | list.end, |
| 2152 | addr_info.alignment, |
| 2153 | .{ .read = true }, |
| 2154 | ); |
| 2104 | 2155 | |
| 2105 | 2156 | const start_sym = start_osmi.symbol(coff).get(coff); |
| 2106 | 2157 | try start_sym.ni.resize(&coff.mf, gpa, addr_info.size); |
| ... | ... | @@ -2460,6 +2511,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2460 | 2511 | .type = .unknown, |
| 2461 | 2512 | .dll_storage_class = .default, |
| 2462 | 2513 | .weak_external_strat = undefined, |
| 2514 | .is_entry = false, |
| 2463 | 2515 | }, |
| 2464 | 2516 | .loc_relocs = .none, |
| 2465 | 2517 | .target_relocs = .none, |
| ... | ... | @@ -2482,14 +2534,14 @@ fn getOrPutString(coff: *Coff, string: []const u8) !String { |
| 2482 | 2534 | fn getOrPutOptionalString(coff: *Coff, string: ?[]const u8) !String.Optional { |
| 2483 | 2535 | return (try coff.getOrPutString(string orelse return .none)).toOptional(); |
| 2484 | 2536 | } |
| 2485 | | fn getString(coff: *Coff, string: []const u8) ?String { |
| 2537 | fn getString(coff: *Coff, string: []const u8) String.Optional { |
| 2486 | 2538 | if (coff.strings.getKeyAdapted( |
| 2487 | 2539 | string, |
| 2488 | 2540 | std.hash_map.StringIndexAdapter{ .bytes = &coff.string_bytes }, |
| 2489 | 2541 | )) |key| |
| 2490 | | return @enumFromInt(key) |
| 2542 | return @as(String, @enumFromInt(key)).toOptional() |
| 2491 | 2543 | else |
| 2492 | | return null; |
| 2544 | return .none; |
| 2493 | 2545 | } |
| 2494 | 2546 | |
| 2495 | 2547 | /// If the name does not fit in the symbol header, adds it to the symbol table string table. |
| ... | ... | @@ -4882,12 +4934,13 @@ fn loadDll(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { |
| 4882 | 4934 | |
| 4883 | 4935 | pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { |
| 4884 | 4936 | _ = prog_node; |
| 4937 | const base = coff.base; |
| 4938 | const comp = base.comp; |
| 4939 | |
| 4885 | 4940 | log.debug("prelink()", .{}); |
| 4886 | 4941 | |
| 4887 | 4942 | if (coff.pending_default_libs.items.len > 0) { |
| 4888 | 4943 | // Libs provided by /DEFAULTLIB arguments in objects are searched after all other inputs |
| 4889 | | const base = coff.base; |
| 4890 | | const comp = base.comp; |
| 4891 | 4944 | const gpa = comp.gpa; |
| 4892 | 4945 | const arena = comp.arena; |
| 4893 | 4946 | const target = &comp.root_mod.resolved_target.result; |
| ... | ... | @@ -4949,6 +5002,34 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { |
| 4949 | 5002 | } |
| 4950 | 5003 | } |
| 4951 | 5004 | |
| 5005 | if (coff.isImage() and comp.config.link_libc) { |
| 5006 | const entries: []const struct { ?[]const u8, []const u8 } = if (coff.isExe()) |
| 5007 | if (comp.zcu == null) switch (coff.optionalHeaderField(.subsystem)) { |
| 5008 | .WINDOWS_CUI => &.{ |
| 5009 | .{ "main", "mainCRTStartup" }, |
| 5010 | .{ "wmain", "wmainCRTStartup" }, |
| 5011 | }, |
| 5012 | .WINDOWS_GUI => &.{ |
| 5013 | .{ "WinMain", "WinMainCRTStartup" }, |
| 5014 | .{ "wWinMain", "wWinMainCRTStartup" }, |
| 5015 | }, |
| 5016 | else => unreachable, |
| 5017 | } else &.{} |
| 5018 | else |
| 5019 | &.{.{ null, "_DllMainCRTStartup" }}; |
| 5020 | |
| 5021 | for (entries) |entry| { |
| 5022 | if (entry[0]) |required_name| { |
| 5023 | const str = coff.getString(required_name).unwrap() orelse continue; |
| 5024 | const si = coff.globals.get(.{ .name = str, .lib_name = .none }) orelse continue; |
| 5025 | if (si.get(coff).ni == .none) continue; |
| 5026 | } |
| 5027 | |
| 5028 | const si = try coff.globalSymbol(.{ .name = entry[1], .type = .code }); |
| 5029 | coff.updateEntry(si.get(coff).gmi); |
| 5030 | } |
| 5031 | } |
| 5032 | |
| 4952 | 5033 | coff.inputs_complete = true; |
| 4953 | 5034 | } |
| 4954 | 5035 | |
| ... | ... | @@ -5241,6 +5322,17 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5241 | 5322 | const gpa = comp.gpa; |
| 5242 | 5323 | const max_notes = 4; |
| 5243 | 5324 | |
| 5325 | if (coff.isImage()) { |
| 5326 | if (coff.entry == .none) |
| 5327 | comp.link_diags.addError("no entry point defined", .{}) |
| 5328 | else if (coff.entry.symbol(coff).get(coff).ni == .none) { |
| 5329 | comp.link_diags.addError( |
| 5330 | "no definition for entry point '{s}' found", |
| 5331 | .{coff.entry.globalName(coff).name.toSlice(coff)}, |
| 5332 | ); |
| 5333 | } |
| 5334 | } |
| 5335 | |
| 5244 | 5336 | var undef_indices: std.ArrayListUnmanaged(u32) = .empty; |
| 5245 | 5337 | for (coff.relocs.items, 0..) |reloc, reloc_i| { |
| 5246 | 5338 | const target_sym = reloc.target.get(coff); |
| ... | ... | @@ -5988,6 +6080,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 5988 | 6080 | .import_lookup_table_ni = import_lookup_table_ni, |
| 5989 | 6081 | .import_address_table_si = import_address_table_si, |
| 5990 | 6082 | .import_hint_name_table_ni = import_hint_name_table_ni, |
| 6083 | .import_address_table_symbols = .empty, |
| 5991 | 6084 | .len = 0, |
| 5992 | 6085 | .hint_name_len = @intCast(import_hint_name_table_len), |
| 5993 | 6086 | }; |
| ... | ... | @@ -6034,20 +6127,20 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6034 | 6127 | gop.value_ptr.len = import_symbol_index + 1; |
| 6035 | 6128 | const new_symbol_table_size = addr_info.size * (import_symbol_index + 2); |
| 6036 | 6129 | |
| 6130 | try gop.value_ptr.import_lookup_table_ni.resize(&coff.mf, gpa, new_symbol_table_size); |
| 6131 | const import_address_table_ni = gop.value_ptr.import_address_table_si.node(coff); |
| 6132 | try import_address_table_ni.resize(&coff.mf, gpa, new_symbol_table_size); |
| 6133 | |
| 6037 | 6134 | const opt_name = import.name.toSlice(coff); |
| 6038 | 6135 | const opt_import_hint_name_index = if (opt_name) |name| blk: { |
| 6039 | 6136 | const import_hint_name_index = gop.value_ptr.hint_name_len; |
| 6040 | 6137 | gop.value_ptr.hint_name_len = @intCast( |
| 6041 | 6138 | import_hint_name_align.forward(import_hint_name_index + 2 + name.len + 1), |
| 6042 | 6139 | ); |
| 6140 | try gop.value_ptr.import_hint_name_table_ni.resize(&coff.mf, gpa, gop.value_ptr.hint_name_len); |
| 6043 | 6141 | break :blk import_hint_name_index; |
| 6044 | 6142 | } else null; |
| 6045 | 6143 | |
| 6046 | | try gop.value_ptr.import_lookup_table_ni.resize(&coff.mf, gpa, new_symbol_table_size); |
| 6047 | | const import_address_table_ni = gop.value_ptr.import_address_table_si.node(coff); |
| 6048 | | try import_address_table_ni.resize(&coff.mf, gpa, new_symbol_table_size); |
| 6049 | | try gop.value_ptr.import_hint_name_table_ni.resize(&coff.mf, gpa, gop.value_ptr.hint_name_len); |
| 6050 | | |
| 6051 | 6144 | const import_hint_name_rva = if (opt_import_hint_name_index) |import_hint_name_index| blk: { |
| 6052 | 6145 | const import_hint_name_slice = gop.value_ptr.import_hint_name_table_ni.slice(&coff.mf); |
| 6053 | 6146 | const ordinal_hint: *u16 = @ptrCast(@alignCast(import_hint_name_slice[import_hint_name_index..][0..2])); |
| ... | ... | @@ -6062,26 +6155,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6062 | 6155 | switch (addr_info.magic) { |
| 6063 | 6156 | _ => unreachable, |
| 6064 | 6157 | inline .PE32, .@"PE32+" => |ct_magic| { |
| 6065 | | const Payload = packed union(u31) { |
| 6066 | | ordinal: packed struct(u31) { |
| 6067 | | ordinal: u16, |
| 6068 | | _: u15 = 0, |
| 6069 | | }, |
| 6070 | | hint_name_rva: u31, |
| 6071 | | }; |
| 6072 | | |
| 6073 | | const Entry = switch (ct_magic) { |
| 6074 | | _ => comptime unreachable, |
| 6075 | | .PE32 => packed struct(u32) { |
| 6076 | | payload: Payload, |
| 6077 | | is_ordinal: bool, |
| 6078 | | }, |
| 6079 | | .@"PE32+" => packed struct(u64) { |
| 6080 | | payload: Payload, |
| 6081 | | _: u32 = 0, |
| 6082 | | is_ordinal: bool, |
| 6083 | | }, |
| 6084 | | }; |
| 6158 | const Entry = ImportTable.TableEntry(ct_magic); |
| 6085 | 6159 | const import_lookup_table: []Entry = @ptrCast(@alignCast(import_lookup_slice)); |
| 6086 | 6160 | const import_address_table: []Entry = @ptrCast(@alignCast(import_address_slice)); |
| 6087 | 6161 | const import_hint_name_rvas: [2]Entry = .{ |
| ... | ... | @@ -6112,6 +6186,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6112 | 6186 | sym.ni = iat_sym.ni; |
| 6113 | 6187 | sym.setValue(.{ .node_offset = iat_offset }); |
| 6114 | 6188 | si.flushMoved(coff); |
| 6189 | (try gop.value_ptr.import_address_table_symbols.addOne(gpa)).* = si; |
| 6115 | 6190 | }, |
| 6116 | 6191 | .thunk => { |
| 6117 | 6192 | sym.section_number = Symbol.Index.text.get(coff).section_number; |
| ... | ... | @@ -6281,15 +6356,18 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6281 | 6356 | coff.computeNodeRva(ni), |
| 6282 | 6357 | ), |
| 6283 | 6358 | .import_address_table => |import_index| { |
| 6284 | | const import_address_table_si = import_index.get(coff).import_address_table_si; |
| 6359 | const entry = import_index.get(coff); |
| 6360 | const import_address_table_si = entry.import_address_table_si; |
| 6285 | 6361 | import_address_table_si.flushMoved(coff); |
| 6286 | 6362 | coff.targetStore( |
| 6287 | 6363 | &coff.importDirectoryEntryPtr(import_index).import_address_table_rva, |
| 6288 | 6364 | import_address_table_si.get(coff).rva, |
| 6289 | 6365 | ); |
| 6366 | |
| 6367 | for (entry.import_address_table_symbols.items) |iat_ptr_si| |
| 6368 | iat_ptr_si.flushMoved(coff); |
| 6290 | 6369 | }, |
| 6291 | 6370 | .import_hint_name_table => |import_index| { |
| 6292 | | const target_endian = coff.targetEndian(); |
| 6293 | 6371 | const magic = coff.targetLoad(&coff.optionalHeaderStandardPtr().magic); |
| 6294 | 6372 | const import_hint_name_rva = coff.computeNodeRva(ni); |
| 6295 | 6373 | coff.targetStore( |
| ... | ... | @@ -6302,32 +6380,36 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6302 | 6380 | import_entry.import_address_table_si.node(coff).slice(&coff.mf); |
| 6303 | 6381 | const import_hint_name_slice = ni.slice(&coff.mf); |
| 6304 | 6382 | const import_hint_name_align = ni.alignment(&coff.mf); |
| 6383 | |
| 6305 | 6384 | var import_hint_name_index: u32 = 0; |
| 6306 | 6385 | for (0..import_entry.len) |import_symbol_index| { |
| 6307 | | import_hint_name_index = @intCast(import_hint_name_align.forward( |
| 6308 | | std.mem.indexOfScalarPos( |
| 6309 | | u8, |
| 6310 | | import_hint_name_slice, |
| 6311 | | import_hint_name_index, |
| 6312 | | 0, |
| 6313 | | ).? + 1, |
| 6314 | | )); |
| 6315 | 6386 | switch (magic) { |
| 6316 | 6387 | _ => unreachable, |
| 6317 | 6388 | inline .PE32, .@"PE32+" => |ct_magic| { |
| 6318 | | const Addr = TargetAddr(ct_magic); |
| 6319 | | const import_lookup_table: []Addr = @ptrCast(@alignCast(import_lookup_slice)); |
| 6320 | | const import_address_table: []Addr = @ptrCast(@alignCast(import_address_slice)); |
| 6321 | | const rva = std.mem.nativeTo( |
| 6322 | | Addr, |
| 6323 | | import_hint_name_rva + import_hint_name_index, |
| 6324 | | target_endian, |
| 6325 | | ); |
| 6326 | | import_lookup_table[import_symbol_index] = rva; |
| 6327 | | import_address_table[import_symbol_index] = rva; |
| 6389 | const Entry = ImportTable.TableEntry(ct_magic); |
| 6390 | const import_lookup_table: []Entry = @ptrCast(@alignCast(import_lookup_slice)); |
| 6391 | const import_address_table: []Entry = @ptrCast(@alignCast(import_address_slice)); |
| 6392 | |
| 6393 | var entry = coff.targetLoad(&import_lookup_table[import_symbol_index]); |
| 6394 | if (entry.is_ordinal) |
| 6395 | continue; |
| 6396 | |
| 6397 | import_hint_name_index = @intCast(import_hint_name_align.forward( |
| 6398 | std.mem.indexOfScalarPos( |
| 6399 | u8, |
| 6400 | import_hint_name_slice, |
| 6401 | import_hint_name_index, |
| 6402 | 0, |
| 6403 | ).? + 1, |
| 6404 | )); |
| 6405 | |
| 6406 | entry.payload.hint_name_rva = @intCast(import_hint_name_rva + import_hint_name_index); |
| 6407 | import_hint_name_index += 2; |
| 6408 | |
| 6409 | coff.targetStore(&import_lookup_table[import_symbol_index], entry); |
| 6410 | coff.targetStore(&import_address_table[import_symbol_index], entry); |
| 6328 | 6411 | }, |
| 6329 | 6412 | } |
| 6330 | | import_hint_name_index += 2; |
| 6331 | 6413 | } |
| 6332 | 6414 | }, |
| 6333 | 6415 | .export_directory_table => { |
| ... | ... | @@ -6679,14 +6761,16 @@ fn updateExportsInner( |
| 6679 | 6761 | export_sym.section_number = exported_sym.section_number; |
| 6680 | 6762 | defer export_si.applyTargetRelocs(coff); |
| 6681 | 6763 | |
| 6682 | | if (isImage(coff)) { |
| 6683 | | if (@"export".opts.name.eqlSlice("wWinMainCRTStartup", ip)) { |
| 6684 | | coff.optionalHeaderStandardPtr().address_of_entry_point = exported_sym.rva; |
| 6685 | | } else if (@"export".opts.name.eqlSlice("_tls_used", ip)) { |
| 6764 | if (coff.isImage()) { |
| 6765 | if (@"export".opts.name.eqlSlice("_tls_used", ip)) { |
| 6686 | 6766 | const tls_directory = coff.dataDirectoryPtr(.TLS); |
| 6687 | 6767 | tls_directory.* = .{ .virtual_address = exported_sym.rva, .size = exported_sym.value.size }; |
| 6688 | 6768 | if (coff.targetEndian() != native_endian) |
| 6689 | 6769 | std.mem.byteSwapAllFields(std.coff.ImageDataDirectory, tls_directory); |
| 6770 | } else if ((coff.isExe() and @"export".opts.name.eqlSlice("wWinMainCRTStartup", ip)) or |
| 6771 | (!coff.isExe() and @"export".opts.name.eqlSlice("_DllMainCRTStartup", ip))) |
| 6772 | { |
| 6773 | coff.updateEntry(export_sym.gmi); |
| 6690 | 6774 | } |
| 6691 | 6775 | } else continue; |
| 6692 | 6776 | |
| ... | ... | @@ -6780,6 +6864,20 @@ fn updateExportsInner( |
| 6780 | 6864 | } |
| 6781 | 6865 | } |
| 6782 | 6866 | |
| 6867 | /// Caller ensures that `applyTargetRelocs` will be called on `si` eventually |
| 6868 | fn updateEntry(coff: *Coff, gmi: Node.GlobalMapIndex) void { |
| 6869 | const si = gmi.symbol(coff); |
| 6870 | log.debug("updateEntry({s}, {d})", .{ gmi.globalName(coff).name.toSlice(coff), si }); |
| 6871 | |
| 6872 | if (coff.entry != .none) |
| 6873 | coff.entry.symbol(coff).get(coff).flags.is_entry = false; |
| 6874 | |
| 6875 | // TODO: Should we detect the subsystem like link.exe does (if not explicitly set) based on entry name? |
| 6876 | |
| 6877 | coff.entry = gmi; |
| 6878 | si.get(coff).flags.is_entry = true; |
| 6879 | } |
| 6880 | |
| 6783 | 6881 | pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTerminatedString) void { |
| 6784 | 6882 | _ = coff; |
| 6785 | 6883 | _ = exported; |