| ... | ... | @@ -874,14 +874,15 @@ pub const Symbol = struct { |
| 874 | 874 | ni: MappedFile.Node.Index, |
| 875 | 875 | rva: u32, |
| 876 | 876 | value: std.meta.BareUnion(Symbol.Value), |
| 877 | extra: std.meta.BareUnion(Symbol.Extra), |
| 877 | 878 | flags: packed struct(u16) { |
| 878 | 879 | value_tag: ValueTag, |
| 880 | extra_tag: ExtraTag, |
| 879 | 881 | type: Symbol.Type, |
| 880 | 882 | dll_storage_class: DllStorageClass, |
| 881 | 883 | // Only defined for .alias_si and .alias_name |
| 882 | 884 | weak_external_strat: WeakExternalStrat, |
| 883 | | has_alias: bool, |
| 884 | | _: u7 = 0, |
| 885 | _: u6 = 0, |
| 885 | 886 | }, |
| 886 | 887 | /// Relocations contained within this symbol |
| 887 | 888 | loc_relocs: Reloc.Index, |
| ... | ... | @@ -889,16 +890,6 @@ pub const Symbol = struct { |
| 889 | 890 | target_relocs: Reloc.Index, |
| 890 | 891 | section_number: SectionNumber, |
| 891 | 892 | 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 | | }, |
| 902 | 893 | |
| 903 | 894 | pub const DllStorageClass = enum(u2) { |
| 904 | 895 | default, |
| ... | ... | @@ -916,23 +907,41 @@ pub const Symbol = struct { |
| 916 | 907 | node_offset, |
| 917 | 908 | weak_alias_si, |
| 918 | 909 | weak_alias_name, |
| 919 | | size, |
| 910 | sti, |
| 920 | 911 | }; |
| 921 | 912 | |
| 922 | 913 | pub const Value = union(ValueTag) { |
| 923 | 914 | /// The offset of the symbol within its node. Used with symbols that |
| 924 | 915 | /// don't create their own nodes: .input_section, .import_address_table |
| 916 | /// Images only. |
| 925 | 917 | node_offset: u32, |
| 926 | 918 | /// This is a weak alias that can replace this symbol |
| 927 | | /// Globals only. |
| 919 | /// Globals only, images only. |
| 928 | 920 | weak_alias_si: Symbol.Index, |
| 929 | 921 | /// For weak externals that have an alias that is also an undef |
| 930 | 922 | /// external, this is the name of the alias global that should |
| 931 | 923 | /// be generated if this symbol is not resolved. |
| 932 | | /// Globals only. |
| 924 | /// Globals only, images only. |
| 933 | 925 | 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 |
| 935 | 939 | 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, |
| 936 | 945 | }; |
| 937 | 946 | |
| 938 | 947 | pub fn setValue(sym: *Symbol, value: Symbol.Value) void { |
| ... | ... | @@ -946,6 +955,17 @@ pub const Symbol = struct { |
| 946 | 955 | }; |
| 947 | 956 | } |
| 948 | 957 | |
| 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 | |
| 949 | 969 | pub fn nodeOffset(sym: *const Symbol, coff: *Coff) u32 { |
| 950 | 970 | return switch (sym.flags.value_tag) { |
| 951 | 971 | .node_offset => offset: { |
| ... | ... | @@ -961,7 +981,7 @@ pub const Symbol = struct { |
| 961 | 981 | } |
| 962 | 982 | |
| 963 | 983 | 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; |
| 965 | 985 | } |
| 966 | 986 | |
| 967 | 987 | pub const SectionNumber = enum(i16) { |
| ... | ... | @@ -1038,7 +1058,7 @@ pub const Symbol = struct { |
| 1038 | 1058 | si.applyTargetRelocs(coff, .none); |
| 1039 | 1059 | |
| 1040 | 1060 | var alias_sym = sym; |
| 1041 | | while (alias_sym.flags.has_alias) { |
| 1061 | while (alias_sym.flags.extra_tag == .next_alias_si) { |
| 1042 | 1062 | const alias_si = alias_sym.extra.next_alias_si; |
| 1043 | 1063 | alias_sym = alias_si.get(coff); |
| 1044 | 1064 | assert(alias_sym.ni == sym.ni); |
| ... | ... | @@ -1049,7 +1069,7 @@ pub const Symbol = struct { |
| 1049 | 1069 | |
| 1050 | 1070 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { |
| 1051 | 1071 | const sym = si.get(coff); |
| 1052 | | const index = sym.extra.sti.unwrap() orelse return; |
| 1072 | const index = sym.value.sti.unwrap() orelse return; |
| 1053 | 1073 | var ri = sym.target_relocs; |
| 1054 | 1074 | while (ri != .none) { |
| 1055 | 1075 | const reloc = ri.get(coff); |
| ... | ... | @@ -1989,6 +2009,7 @@ fn initHeaders( |
| 1989 | 2009 | .resized = true, |
| 1990 | 2010 | }); |
| 1991 | 2011 | coff.nodes.appendAssumeCapacity(.string_table); |
| 2012 | coff.targetStore(coff.symbolTableStringLenPtr(), @sizeOf(u32)); |
| 1992 | 2013 | } |
| 1993 | 2014 | |
| 1994 | 2015 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); |
| ... | ... | @@ -2193,8 +2214,7 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2193 | 2214 | list_sym.ni = start_sym.ni; |
| 2194 | 2215 | list_sym.section_number = start_sym.section_number; |
| 2195 | 2216 | |
| 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 }); |
| 2198 | 2218 | } |
| 2199 | 2219 | } |
| 2200 | 2220 | } |
| ... | ... | @@ -2483,11 +2503,14 @@ pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.c |
| 2483 | 2503 | return null; |
| 2484 | 2504 | } |
| 2485 | 2505 | |
| 2486 | | pub 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))); |
| 2506 | pub 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 | } |
| 2491 | 2514 | } |
| 2492 | 2515 | |
| 2493 | 2516 | pub fn symbolTableStringLenPtr(coff: *Coff) *align(1) u32 { |
| ... | ... | @@ -2524,19 +2547,19 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2524 | 2547 | defer coff.symbols.addOneAssumeCapacity().* = .{ |
| 2525 | 2548 | .ni = .none, |
| 2526 | 2549 | .rva = 0, |
| 2527 | | .value = .{ .size = 0 }, |
| 2550 | .value = .{ .sti = .none }, |
| 2551 | .extra = .{ .size = 0 }, |
| 2528 | 2552 | .flags = .{ |
| 2529 | | .value_tag = .size, |
| 2553 | .value_tag = .sti, |
| 2554 | .extra_tag = .size, |
| 2530 | 2555 | .type = .unknown, |
| 2531 | 2556 | .dll_storage_class = .default, |
| 2532 | 2557 | .weak_external_strat = undefined, |
| 2533 | | .has_alias = false, |
| 2534 | 2558 | }, |
| 2535 | 2559 | .loc_relocs = .none, |
| 2536 | 2560 | .target_relocs = .none, |
| 2537 | 2561 | .section_number = .UNDEFINED, |
| 2538 | 2562 | .gmi = .none, |
| 2539 | | .extra = .{ .sti = .none }, |
| 2540 | 2563 | }; |
| 2541 | 2564 | return @enumFromInt(coff.symbols.items.len); |
| 2542 | 2565 | } |
| ... | ... | @@ -2975,7 +2998,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 2975 | 2998 | const sym = si.get(coff); |
| 2976 | 2999 | assert(sym.ni != .none or sym.gmi != .none); |
| 2977 | 3000 | |
| 2978 | | const entry = coff.symbolTableEntryPtr(sym.extra.sti) orelse entry: { |
| 3001 | const entry = coff.symbolTableEntryPtr(sym.value.sti) orelse entry: { |
| 2979 | 3002 | var buf: [15]u8 = undefined; |
| 2980 | 3003 | const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType = |
| 2981 | 3004 | if (sym.gmi != .none) blk: { |
| ... | ... | @@ -3040,10 +3063,11 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3040 | 3063 | try coff.symbol_table.ni.resize(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf()); |
| 3041 | 3064 | |
| 3042 | 3065 | 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); |
| 3044 | 3068 | si.flushSymbolTableIndex(coff); |
| 3045 | 3069 | |
| 3046 | | const entry = coff.symbolTableEntryPtr(sym.extra.sti).?; |
| 3070 | const entry = coff.symbolTableEntryPtr(sym.value.sti).?; |
| 3047 | 3071 | symbol_name.store(coff, &entry.name); |
| 3048 | 3072 | |
| 3049 | 3073 | entry.section_number = @enumFromInt(@intFromEnum(sym.section_number)); |
| ... | ... | @@ -3056,8 +3080,31 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3056 | 3080 | if (coff.targetEndian() != native_endian) |
| 3057 | 3081 | std.mem.byteSwapAllFieldsAligned(std.coff.Symbol, .@"2", entry); |
| 3058 | 3082 | |
| 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 | } |
| 3061 | 3108 | |
| 3062 | 3109 | break :entry entry; |
| 3063 | 3110 | }; |
| ... | ... | @@ -3073,7 +3120,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3073 | 3120 | }, |
| 3074 | 3121 | }); |
| 3075 | 3122 | |
| 3076 | | log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sym.extra.sti }); |
| 3123 | log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sym.value.sti }); |
| 3077 | 3124 | } |
| 3078 | 3125 | |
| 3079 | 3126 | fn flushInputMember(coff: *Coff, iami: InputArchive.Member.Index) !void { |
| ... | ... | @@ -3478,8 +3525,8 @@ pub fn addReloc( |
| 3478 | 3525 | else => |loc_sn| sri: { |
| 3479 | 3526 | // The target may not have a node yet, or it could be an extern that will never |
| 3480 | 3527 | // 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 |
| 3483 | 3530 | else if (target.ni != .none) sti: { |
| 3484 | 3531 | try coff.pendingSymbolTableEntry(target_si); |
| 3485 | 3532 | break :sti .none; |
| ... | ... | @@ -3503,14 +3550,9 @@ pub fn addReloc( |
| 3503 | 3550 | try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); |
| 3504 | 3551 | } |
| 3505 | 3552 | |
| 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); |
| 3514 | 3556 | |
| 3515 | 3557 | // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?) |
| 3516 | 3558 | const sri: Section.RelocationIndex = .wrap(old_num_relocations); |
| ... | ... | @@ -3643,7 +3685,7 @@ fn loadObject( |
| 3643 | 3685 | |
| 3644 | 3686 | log.debug("loadObject({f}{f})", .{ path.fmtEscapeString(), fmtMemberNameString(member_name) }); |
| 3645 | 3687 | |
| 3646 | | const header = try r.peekStruct(std.coff.Header, .little()); |
| 3688 | const header = try r.peekStruct(std.coff.Header, .little); |
| 3647 | 3689 | if (header.machine != target.toCoffMachine()) |
| 3648 | 3690 | return diags.failParse(path, "machine mismatch: expected {t}, found {t}", .{ |
| 3649 | 3691 | target.toCoffMachine(), |
| ... | ... | @@ -3678,7 +3720,7 @@ fn loadObject( |
| 3678 | 3720 | const string_table_len = try r.peekInt(u32, target_endian); |
| 3679 | 3721 | if (string_table_len < @sizeOf(u32) or |
| 3680 | 3722 | 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}); |
| 3682 | 3724 | |
| 3683 | 3725 | const ioi: InputObject.Index = @enumFromInt(coff.input_objects.items.len); |
| 3684 | 3726 | try coff.input_objects.ensureUnusedCapacity(gpa, 1); |
| ... | ... | @@ -4519,17 +4561,18 @@ fn loadObject( |
| 4519 | 4561 | const sym = symbol.si.get(coff); |
| 4520 | 4562 | assert(sym.ni == .none); |
| 4521 | 4563 | 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 }), |
| 4525 | 4567 | .external => |v| switch (symbol.section_number) { |
| 4526 | 4568 | .UNDEFINED, .ABSOLUTE, .DEBUG => unreachable, |
| 4527 | | else => .{ .node_offset = v }, |
| 4569 | else => sym.setValue(.{ .node_offset = v }), |
| 4528 | 4570 | }, |
| 4529 | 4571 | .weak_external, |
| 4530 | 4572 | .weak_external_aux, |
| 4531 | 4573 | => unreachable, |
| 4532 | | }); |
| 4574 | } |
| 4575 | |
| 4533 | 4576 | sym.section_number = section.si.get(coff).section_number; |
| 4534 | 4577 | } |
| 4535 | 4578 | } |
| ... | ... | @@ -4572,7 +4615,7 @@ fn loadObject( |
| 4572 | 4615 | symbol.si = global_gop.value_ptr.*; |
| 4573 | 4616 | if (!global_gop.found_existing or symbol.si.get(coff).ni == .none) { |
| 4574 | 4617 | const sym = symbol.si.get(coff); |
| 4575 | | sym.setValue(.{ .size = @max(sym.size(), size) }); |
| 4618 | sym.setExtra(.{ .size = @max(sym.size(), size) }); |
| 4576 | 4619 | } |
| 4577 | 4620 | }, |
| 4578 | 4621 | else => unreachable, |
| ... | ... | @@ -5156,12 +5199,12 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5156 | 5199 | error.WriteFailed => return nw.err.?, |
| 5157 | 5200 | else => |e| return e, |
| 5158 | 5201 | }; |
| 5159 | | si.get(coff).value.size = @intCast(nw.interface.end); |
| 5202 | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 5160 | 5203 | si.applyLocationRelocs(coff); |
| 5161 | 5204 | } |
| 5162 | 5205 | |
| 5163 | 5206 | 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); |
| 5165 | 5208 | var parent_ni = ni; |
| 5166 | 5209 | while (true) { |
| 5167 | 5210 | parent_ni = parent_ni.parent(&coff.mf); |
| ... | ... | @@ -5289,7 +5332,7 @@ fn updateFuncInner( |
| 5289 | 5332 | error.WriteFailed => return nw.err.?, |
| 5290 | 5333 | else => |e| return e, |
| 5291 | 5334 | }; |
| 5292 | | si.get(coff).value.size = @intCast(nw.interface.end); |
| 5335 | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 5293 | 5336 | si.applyLocationRelocs(coff); |
| 5294 | 5337 | } |
| 5295 | 5338 | |
| ... | ... | @@ -5533,6 +5576,7 @@ pub fn flush( |
| 5533 | 5576 | ) !void { |
| 5534 | 5577 | _ = arena; |
| 5535 | 5578 | _ = prog_node; |
| 5579 | const comp = coff.base.comp; |
| 5536 | 5580 | |
| 5537 | 5581 | // TODO: When https://github.com/ziglang/zig/issues/23617 is in, |
| 5538 | 5582 | // this should be set after updateExports instead |
| ... | ... | @@ -5541,11 +5585,30 @@ pub fn flush( |
| 5541 | 5585 | while (try coff.resolve(tid)) {} |
| 5542 | 5586 | while (try coff.idle(tid)) {} |
| 5543 | 5587 | |
| 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 | |
| 5544 | 5609 | if (coff.isImage()) |
| 5545 | 5610 | try coff.reportUndefs(tid); |
| 5546 | 5611 | |
| 5547 | | const comp = coff.base.comp; |
| 5548 | | |
| 5549 | 5612 | // Implib generation should instead be done via building a MappedFile progressively |
| 5550 | 5613 | if (comp.emit_implib) |implib_file| |
| 5551 | 5614 | coff.flushImplib(implib_file) catch |err| |
| ... | ... | @@ -5717,31 +5780,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5717 | 5780 | }; |
| 5718 | 5781 | break :task; |
| 5719 | 5782 | } |
| 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 | | } |
| 5745 | 5783 | } |
| 5746 | 5784 | |
| 5747 | 5785 | 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 { |
| 5753 | 5791 | if (coff.exports_complete and coff.pending_special_symbol != .none) return true; |
| 5754 | 5792 | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; |
| 5755 | 5793 | if (coff.symbol_table.pending.count() > 0) return true; |
| 5756 | | if (coff.symbol_table.pending_shrink) return true; |
| 5757 | 5794 | return false; |
| 5758 | 5795 | } |
| 5759 | 5796 | |
| ... | ... | @@ -5922,7 +5959,7 @@ fn flushUav( |
| 5922 | 5959 | error.WriteFailed => return nw.err.?, |
| 5923 | 5960 | else => |e| return e, |
| 5924 | 5961 | }; |
| 5925 | | si.get(coff).value.size = @intCast(nw.interface.end); |
| 5962 | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 5926 | 5963 | si.applyLocationRelocs(coff); |
| 5927 | 5964 | } |
| 5928 | 5965 | |
| ... | ... | @@ -6358,7 +6395,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6358 | 6395 | }); |
| 6359 | 6396 | @memcpy(ni.slice(&coff.mf)[0..init.len], &init); |
| 6360 | 6397 | sym.ni = ni; |
| 6361 | | sym.setValue(.{ .size = init.len }); |
| 6398 | sym.extra.size = init.len; |
| 6362 | 6399 | try coff.addReloc( |
| 6363 | 6400 | si, |
| 6364 | 6401 | init.len - 4, |
| ... | ... | @@ -6539,7 +6576,7 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6539 | 6576 | error.WriteFailed => return nw.err.?, |
| 6540 | 6577 | else => |e| return e, |
| 6541 | 6578 | }; |
| 6542 | | si.get(coff).value.size = @intCast(nw.interface.end); |
| 6579 | si.get(coff).extra.size = @intCast(nw.interface.end); |
| 6543 | 6580 | si.applyLocationRelocs(coff); |
| 6544 | 6581 | } |
| 6545 | 6582 | |
| ... | ... | @@ -6556,13 +6593,15 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6556 | 6593 | .section_table, |
| 6557 | 6594 | .placeholder, |
| 6558 | 6595 | => 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 | |
| 6566 | 6605 | if (!coff.symbol_table.pending_shrink) { |
| 6567 | 6606 | const symbol_table_loc, const symbol_table_size = coff.symbol_table.ni.location(&coff.mf).resolve(&coff.mf); |
| 6568 | 6607 | 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 { |
| 6822 | 6861 | } |
| 6823 | 6862 | |
| 6824 | 6863 | 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)); |
| 6829 | 6866 | } |
| 6830 | 6867 | }, |
| 6831 | 6868 | .input_section => {}, |
| ... | ... | @@ -6853,7 +6890,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6853 | 6890 | ); |
| 6854 | 6891 | } |
| 6855 | 6892 | |
| 6856 | | smi.symbol(coff).get(coff).value.size = @intCast(size); |
| 6893 | smi.symbol(coff).get(coff).extra.size = @intCast(size); |
| 6857 | 6894 | }, |
| 6858 | 6895 | .import_thunk, |
| 6859 | 6896 | .nav, |
| ... | ... | @@ -7091,14 +7128,16 @@ fn updateExportsInner( |
| 7091 | 7128 | const export_sym = export_si.get(coff); |
| 7092 | 7129 | export_sym.ni = exported_ni; |
| 7093 | 7130 | export_sym.rva = exported_sym.rva; |
| 7094 | | export_sym.setValue(.{ .size = exported_sym.value.size }); |
| 7095 | 7131 | export_sym.section_number = exported_sym.section_number; |
| 7096 | 7132 | defer export_si.applyTargetRelocs(coff, .none); |
| 7097 | 7133 | |
| 7098 | 7134 | 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 }); |
| 7102 | 7141 | prev_alias_si = export_si; |
| 7103 | 7142 | |
| 7104 | 7143 | if (!coff.isImage()) continue; |
| ... | ... | @@ -7237,7 +7276,7 @@ fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) !voi |
| 7237 | 7276 | try w.print("{d:0>6}@{d:0>2} {x:08} n{d:0>8} | {s}\n", .{ |
| 7238 | 7277 | si, |
| 7239 | 7278 | 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, |
| 7241 | 7280 | sym.ni, |
| 7242 | 7281 | name.toSlice(coff), |
| 7243 | 7282 | }); |
| ... | ... | @@ -7251,11 +7290,11 @@ fn printSymbol( |
| 7251 | 7290 | ) !void { |
| 7252 | 7291 | const sym = si.get(coff); |
| 7253 | 7292 | 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} ", .{ |
| 7255 | 7294 | si, |
| 7256 | 7295 | 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) |
| 7259 | 7298 | else if (sym.ni != .none) |
| 7260 | 7299 | sym.ni.location(&coff.mf).resolve(&coff.mf)[1] |
| 7261 | 7300 | else |
| ... | ... | @@ -7264,7 +7303,12 @@ fn printSymbol( |
| 7264 | 7303 | .weak_alias_name => "an", |
| 7265 | 7304 | .weak_alias_si => "as", |
| 7266 | 7305 | .node_offset => "no", |
| 7306 | .sti => "st", |
| 7307 | }, |
| 7308 | switch (sym.flags.extra_tag) { |
| 7267 | 7309 | .size => "sz", |
| 7310 | .isli => "li", |
| 7311 | .next_alias_si => "na", |
| 7268 | 7312 | }, |
| 7269 | 7313 | switch (sym.flags.type) { |
| 7270 | 7314 | .unknown => "u", |