| ... | @@ -874,14 +874,15 @@ pub const Symbol = struct { | ... | @@ -874,14 +874,15 @@ pub const Symbol = struct { |
| 874 | ni: MappedFile.Node.Index, | 874 | ni: MappedFile.Node.Index, |
| 875 | rva: u32, | 875 | rva: u32, |
| 876 | value: std.meta.BareUnion(Symbol.Value), | 876 | value: std.meta.BareUnion(Symbol.Value), |
| | 877 | extra: std.meta.BareUnion(Symbol.Extra), |
| 877 | flags: packed struct(u16) { | 878 | flags: packed struct(u16) { |
| 878 | value_tag: ValueTag, | 879 | value_tag: ValueTag, |
| | 880 | extra_tag: ExtraTag, |
| 879 | type: Symbol.Type, | 881 | type: Symbol.Type, |
| 880 | dll_storage_class: DllStorageClass, | 882 | dll_storage_class: DllStorageClass, |
| 881 | // Only defined for .alias_si and .alias_name | 883 | // Only defined for .alias_si and .alias_name |
| 882 | weak_external_strat: WeakExternalStrat, | 884 | weak_external_strat: WeakExternalStrat, |
| 883 | has_alias: bool, | 885 | _: u6 = 0, |
| 884 | _: u7 = 0, | | |
| 885 | }, | 886 | }, |
| 886 | /// Relocations contained within this symbol | 887 | /// Relocations contained within this symbol |
| 887 | loc_relocs: Reloc.Index, | 888 | loc_relocs: Reloc.Index, |
| ... | @@ -889,16 +890,6 @@ pub const Symbol = struct { | ... | @@ -889,16 +890,6 @@ pub const Symbol = struct { |
| 889 | target_relocs: Reloc.Index, | 890 | target_relocs: Reloc.Index, |
| 890 | section_number: SectionNumber, | 891 | section_number: SectionNumber, |
| 891 | gmi: Node.GlobalMapIndex, | 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 | pub const DllStorageClass = enum(u2) { | 894 | pub const DllStorageClass = enum(u2) { |
| 904 | default, | 895 | default, |
| ... | @@ -916,23 +907,41 @@ pub const Symbol = struct { | ... | @@ -916,23 +907,41 @@ pub const Symbol = struct { |
| 916 | node_offset, | 907 | node_offset, |
| 917 | weak_alias_si, | 908 | weak_alias_si, |
| 918 | weak_alias_name, | 909 | weak_alias_name, |
| 919 | size, | 910 | sti, |
| 920 | }; | 911 | }; |
| 921 | | 912 | |
| 922 | pub const Value = union(ValueTag) { | 913 | pub const Value = union(ValueTag) { |
| 923 | /// The offset of the symbol within its node. Used with symbols that | 914 | /// The offset of the symbol within its node. Used with symbols that |
| 924 | /// don't create their own nodes: .input_section, .import_address_table | 915 | /// don't create their own nodes: .input_section, .import_address_table |
| | 916 | /// Images only. |
| 925 | node_offset: u32, | 917 | node_offset: u32, |
| 926 | /// This is a weak alias that can replace this symbol | 918 | /// This is a weak alias that can replace this symbol |
| 927 | /// Globals only. | 919 | /// Globals only, images only. |
| 928 | weak_alias_si: Symbol.Index, | 920 | weak_alias_si: Symbol.Index, |
| 929 | /// For weak externals that have an alias that is also an undef | 921 | /// For weak externals that have an alias that is also an undef |
| 930 | /// external, this is the name of the alias global that should | 922 | /// external, this is the name of the alias global that should |
| 931 | /// be generated if this symbol is not resolved. | 923 | /// be generated if this symbol is not resolved. |
| 932 | /// Globals only. | 924 | /// Globals only, images only. |
| 933 | weak_alias_name: String, | 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 | size: u32, | 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 | pub fn setValue(sym: *Symbol, value: Symbol.Value) void { | 947 | pub fn setValue(sym: *Symbol, value: Symbol.Value) void { |
| ... | @@ -946,6 +955,17 @@ pub const Symbol = struct { | ... | @@ -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 | pub fn nodeOffset(sym: *const Symbol, coff: *Coff) u32 { | 969 | pub fn nodeOffset(sym: *const Symbol, coff: *Coff) u32 { |
| 950 | return switch (sym.flags.value_tag) { | 970 | return switch (sym.flags.value_tag) { |
| 951 | .node_offset => offset: { | 971 | .node_offset => offset: { |
| ... | @@ -961,7 +981,7 @@ pub const Symbol = struct { | ... | @@ -961,7 +981,7 @@ pub const Symbol = struct { |
| 961 | } | 981 | } |
| 962 | | 982 | |
| 963 | pub fn size(sym: *const Symbol) u32 { | 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 | pub const SectionNumber = enum(i16) { | 987 | pub const SectionNumber = enum(i16) { |
| ... | @@ -1038,7 +1058,7 @@ pub const Symbol = struct { | ... | @@ -1038,7 +1058,7 @@ pub const Symbol = struct { |
| 1038 | si.applyTargetRelocs(coff, .none); | 1058 | si.applyTargetRelocs(coff, .none); |
| 1039 | | 1059 | |
| 1040 | var alias_sym = sym; | 1060 | var alias_sym = sym; |
| 1041 | while (alias_sym.flags.has_alias) { | 1061 | while (alias_sym.flags.extra_tag == .next_alias_si) { |
| 1042 | const alias_si = alias_sym.extra.next_alias_si; | 1062 | const alias_si = alias_sym.extra.next_alias_si; |
| 1043 | alias_sym = alias_si.get(coff); | 1063 | alias_sym = alias_si.get(coff); |
| 1044 | assert(alias_sym.ni == sym.ni); | 1064 | assert(alias_sym.ni == sym.ni); |
| ... | @@ -1049,7 +1069,7 @@ pub const Symbol = struct { | ... | @@ -1049,7 +1069,7 @@ pub const Symbol = struct { |
| 1049 | | 1069 | |
| 1050 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { | 1070 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { |
| 1051 | const sym = si.get(coff); | 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 | var ri = sym.target_relocs; | 1073 | var ri = sym.target_relocs; |
| 1054 | while (ri != .none) { | 1074 | while (ri != .none) { |
| 1055 | const reloc = ri.get(coff); | 1075 | const reloc = ri.get(coff); |
| ... | @@ -1989,6 +2009,7 @@ fn initHeaders( | ... | @@ -1989,6 +2009,7 @@ fn initHeaders( |
| 1989 | .resized = true, | 2009 | .resized = true, |
| 1990 | }); | 2010 | }); |
| 1991 | coff.nodes.appendAssumeCapacity(.string_table); | 2011 | coff.nodes.appendAssumeCapacity(.string_table); |
| | 2012 | coff.targetStore(coff.symbolTableStringLenPtr(), @sizeOf(u32)); |
| 1992 | } | 2013 | } |
| 1993 | | 2014 | |
| 1994 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); | 2015 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); |
| ... | @@ -2193,8 +2214,7 @@ pub fn initBuiltins(coff: *Coff) !void { | ... | @@ -2193,8 +2214,7 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2193 | list_sym.ni = start_sym.ni; | 2214 | list_sym.ni = start_sym.ni; |
| 2194 | list_sym.section_number = start_sym.section_number; | 2215 | list_sym.section_number = start_sym.section_number; |
| 2195 | | 2216 | |
| 2196 | start_sym.extra = .{ .next_alias_si = list_si }; | 2217 | start_sym.setExtra(.{ .next_alias_si = list_si }); |
| 2197 | start_sym.flags.has_alias = true; | | |
| 2198 | } | 2218 | } |
| 2199 | } | 2219 | } |
| 2200 | } | 2220 | } |
| ... | @@ -2483,11 +2503,14 @@ pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.c | ... | @@ -2483,11 +2503,14 @@ pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.c |
| 2483 | return null; | 2503 | return null; |
| 2484 | } | 2504 | } |
| 2485 | | 2505 | |
| 2486 | pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) *align(2) std.coff.SectionDefinition { | 2506 | pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) ?*align(2) std.coff.SectionDefinition { |
| 2487 | const sti = si.get(coff).extra.sti; | 2507 | const sti = si.get(coff).value.sti; |
| 2488 | const entry = symbolTableEntryPtr(coff, sti).?; | 2508 | if (symbolTableEntryPtr(coff, sti)) |entry| { |
| 2489 | assert(entry.storage_class == .STATIC and entry.number_of_aux_symbols == 1); | 2509 | assert(entry.storage_class == .STATIC and entry.number_of_aux_symbols == 1); |
| 2490 | return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1))); | 2510 | return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1))); |
| | 2511 | } else { |
| | 2512 | return null; |
| | 2513 | } |
| 2491 | } | 2514 | } |
| 2492 | | 2515 | |
| 2493 | pub fn symbolTableStringLenPtr(coff: *Coff) *align(1) u32 { | 2516 | pub fn symbolTableStringLenPtr(coff: *Coff) *align(1) u32 { |
| ... | @@ -2524,19 +2547,19 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { | ... | @@ -2524,19 +2547,19 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2524 | defer coff.symbols.addOneAssumeCapacity().* = .{ | 2547 | defer coff.symbols.addOneAssumeCapacity().* = .{ |
| 2525 | .ni = .none, | 2548 | .ni = .none, |
| 2526 | .rva = 0, | 2549 | .rva = 0, |
| 2527 | .value = .{ .size = 0 }, | 2550 | .value = .{ .sti = .none }, |
| | 2551 | .extra = .{ .size = 0 }, |
| 2528 | .flags = .{ | 2552 | .flags = .{ |
| 2529 | .value_tag = .size, | 2553 | .value_tag = .sti, |
| | 2554 | .extra_tag = .size, |
| 2530 | .type = .unknown, | 2555 | .type = .unknown, |
| 2531 | .dll_storage_class = .default, | 2556 | .dll_storage_class = .default, |
| 2532 | .weak_external_strat = undefined, | 2557 | .weak_external_strat = undefined, |
| 2533 | .has_alias = false, | | |
| 2534 | }, | 2558 | }, |
| 2535 | .loc_relocs = .none, | 2559 | .loc_relocs = .none, |
| 2536 | .target_relocs = .none, | 2560 | .target_relocs = .none, |
| 2537 | .section_number = .UNDEFINED, | 2561 | .section_number = .UNDEFINED, |
| 2538 | .gmi = .none, | 2562 | .gmi = .none, |
| 2539 | .extra = .{ .sti = .none }, | | |
| 2540 | }; | 2563 | }; |
| 2541 | return @enumFromInt(coff.symbols.items.len); | 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,7 +2998,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 2975 | const sym = si.get(coff); | 2998 | const sym = si.get(coff); |
| 2976 | assert(sym.ni != .none or sym.gmi != .none); | 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 | var buf: [15]u8 = undefined; | 3002 | var buf: [15]u8 = undefined; |
| 2980 | const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType = | 3003 | const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType = |
| 2981 | if (sym.gmi != .none) blk: { | 3004 | if (sym.gmi != .none) blk: { |
| ... | @@ -3040,10 +3063,11 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void | ... | @@ -3040,10 +3063,11 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3040 | try coff.symbol_table.ni.resize(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf()); | 3063 | try coff.symbol_table.ni.resize(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf()); |
| 3041 | | 3064 | |
| 3042 | coff.targetStore(&coff.headerPtr().number_of_symbols, new_num_symbols); | 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 | si.flushSymbolTableIndex(coff); | 3068 | si.flushSymbolTableIndex(coff); |
| 3045 | | 3069 | |
| 3046 | const entry = coff.symbolTableEntryPtr(sym.extra.sti).?; | 3070 | const entry = coff.symbolTableEntryPtr(sym.value.sti).?; |
| 3047 | symbol_name.store(coff, &entry.name); | 3071 | symbol_name.store(coff, &entry.name); |
| 3048 | | 3072 | |
| 3049 | entry.section_number = @enumFromInt(@intFromEnum(sym.section_number)); | 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,8 +3080,31 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3056 | if (coff.targetEndian() != native_endian) | 3080 | if (coff.targetEndian() != native_endian) |
| 3057 | std.mem.byteSwapAllFieldsAligned(std.coff.Symbol, .@"2", entry); | 3081 | std.mem.byteSwapAllFieldsAligned(std.coff.Symbol, .@"2", entry); |
| 3058 | | 3082 | |
| 3059 | for (1..num_aux_symbols + 1) |aux_index| | 3083 | if (num_aux_symbols > 0) aux_init: { |
| 3060 | @memset(coff.symbolTableEntryStoragePtr(@intCast(old_num_symbols + aux_index)), 0); | 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 | break :entry entry; | 3109 | break :entry entry; |
| 3063 | }; | 3110 | }; |
| ... | @@ -3073,7 +3120,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void | ... | @@ -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 | fn flushInputMember(coff: *Coff, iami: InputArchive.Member.Index) !void { | 3126 | fn flushInputMember(coff: *Coff, iami: InputArchive.Member.Index) !void { |
| ... | @@ -3478,8 +3525,8 @@ pub fn addReloc( | ... | @@ -3478,8 +3525,8 @@ pub fn addReloc( |
| 3478 | else => |loc_sn| sri: { | 3525 | else => |loc_sn| sri: { |
| 3479 | // The target may not have a node yet, or it could be an extern that will never | 3526 | // The target may not have a node yet, or it could be an extern that will never |
| 3480 | // have a node. In that case, flushGlobal will create the symbol table entry. | 3527 | // have a node. In that case, flushGlobal will create the symbol table entry. |
| 3481 | const sti: SymbolTable.Index = if (target.extra.sti != .none) | 3528 | const sti: SymbolTable.Index = if (target.value.sti != .none) |
| 3482 | target.extra.sti | 3529 | target.value.sti |
| 3483 | else if (target.ni != .none) sti: { | 3530 | else if (target.ni != .none) sti: { |
| 3484 | try coff.pendingSymbolTableEntry(target_si); | 3531 | try coff.pendingSymbolTableEntry(target_si); |
| 3485 | break :sti .none; | 3532 | break :sti .none; |
| ... | @@ -3503,14 +3550,9 @@ pub fn addReloc( | ... | @@ -3503,14 +3550,9 @@ pub fn addReloc( |
| 3503 | try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); | 3550 | try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); |
| 3504 | } | 3551 | } |
| 3505 | | 3552 | |
| 3506 | coff.targetStore( | 3553 | coff.targetStore(&header.number_of_relocations, new_num_relocations); |
| 3507 | &header.number_of_relocations, | 3554 | if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff))) |aux_ptr| |
| 3508 | new_num_relocations, | 3555 | coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); |
| 3509 | ); | | |
| 3510 | coff.targetStore( | | |
| 3511 | &coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff)).number_of_relocations, | | |
| 3512 | new_num_relocations, | | |
| 3513 | ); | | |
| 3514 | | 3556 | |
| 3515 | // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?) | 3557 | // TODO: These need to allocate from a free list (once deleting relocs is supported) (or can we just remove swap?) |
| 3516 | const sri: Section.RelocationIndex = .wrap(old_num_relocations); | 3558 | const sri: Section.RelocationIndex = .wrap(old_num_relocations); |
| ... | @@ -3643,7 +3685,7 @@ fn loadObject( | ... | @@ -3643,7 +3685,7 @@ fn loadObject( |
| 3643 | | 3685 | |
| 3644 | log.debug("loadObject({f}{f})", .{ path.fmtEscapeString(), fmtMemberNameString(member_name) }); | 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 | if (header.machine != target.toCoffMachine()) | 3689 | if (header.machine != target.toCoffMachine()) |
| 3648 | return diags.failParse(path, "machine mismatch: expected {t}, found {t}", .{ | 3690 | return diags.failParse(path, "machine mismatch: expected {t}, found {t}", .{ |
| 3649 | target.toCoffMachine(), | 3691 | target.toCoffMachine(), |
| ... | @@ -3678,7 +3720,7 @@ fn loadObject( | ... | @@ -3678,7 +3720,7 @@ fn loadObject( |
| 3678 | const string_table_len = try r.peekInt(u32, target_endian); | 3720 | const string_table_len = try r.peekInt(u32, target_endian); |
| 3679 | if (string_table_len < @sizeOf(u32) or | 3721 | if (string_table_len < @sizeOf(u32) or |
| 3680 | symbol_table_end + string_table_len > fl.size) | 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 | const ioi: InputObject.Index = @enumFromInt(coff.input_objects.items.len); | 3725 | const ioi: InputObject.Index = @enumFromInt(coff.input_objects.items.len); |
| 3684 | try coff.input_objects.ensureUnusedCapacity(gpa, 1); | 3726 | try coff.input_objects.ensureUnusedCapacity(gpa, 1); |
| ... | @@ -4519,17 +4561,18 @@ fn loadObject( | ... | @@ -4519,17 +4561,18 @@ fn loadObject( |
| 4519 | const sym = symbol.si.get(coff); | 4561 | const sym = symbol.si.get(coff); |
| 4520 | assert(sym.ni == .none); | 4562 | assert(sym.ni == .none); |
| 4521 | sym.ni = section.si.get(coff).ni; | 4563 | sym.ni = section.si.get(coff).ni; |
| 4522 | sym.setValue(switch (symbol.value) { | 4564 | switch (symbol.value) { |
| 4523 | .section => |v| .{ .size = v }, | 4565 | .section => |v| sym.setExtra(.{ .size = v }), |
| 4524 | .static => |v| .{ .node_offset = v }, | 4566 | .static => |v| sym.setValue(.{ .node_offset = v }), |
| 4525 | .external => |v| switch (symbol.section_number) { | 4567 | .external => |v| switch (symbol.section_number) { |
| 4526 | .UNDEFINED, .ABSOLUTE, .DEBUG => unreachable, | 4568 | .UNDEFINED, .ABSOLUTE, .DEBUG => unreachable, |
| 4527 | else => .{ .node_offset = v }, | 4569 | else => sym.setValue(.{ .node_offset = v }), |
| 4528 | }, | 4570 | }, |
| 4529 | .weak_external, | 4571 | .weak_external, |
| 4530 | .weak_external_aux, | 4572 | .weak_external_aux, |
| 4531 | => unreachable, | 4573 | => unreachable, |
| 4532 | }); | 4574 | } |
| | 4575 | |
| 4533 | sym.section_number = section.si.get(coff).section_number; | 4576 | sym.section_number = section.si.get(coff).section_number; |
| 4534 | } | 4577 | } |
| 4535 | } | 4578 | } |
| ... | @@ -4572,7 +4615,7 @@ fn loadObject( | ... | @@ -4572,7 +4615,7 @@ fn loadObject( |
| 4572 | symbol.si = global_gop.value_ptr.*; | 4615 | symbol.si = global_gop.value_ptr.*; |
| 4573 | if (!global_gop.found_existing or symbol.si.get(coff).ni == .none) { | 4616 | if (!global_gop.found_existing or symbol.si.get(coff).ni == .none) { |
| 4574 | const sym = symbol.si.get(coff); | 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 | else => unreachable, | 4621 | else => unreachable, |
| ... | @@ -5156,12 +5199,12 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -5156,12 +5199,12 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5156 | error.WriteFailed => return nw.err.?, | 5199 | error.WriteFailed => return nw.err.?, |
| 5157 | else => |e| return e, | 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 | si.applyLocationRelocs(coff); | 5203 | si.applyLocationRelocs(coff); |
| 5161 | } | 5204 | } |
| 5162 | | 5205 | |
| 5163 | if (nav.resolved.?.@"linksection".unwrap()) |_| { | 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 | var parent_ni = ni; | 5208 | var parent_ni = ni; |
| 5166 | while (true) { | 5209 | while (true) { |
| 5167 | parent_ni = parent_ni.parent(&coff.mf); | 5210 | parent_ni = parent_ni.parent(&coff.mf); |
| ... | @@ -5289,7 +5332,7 @@ fn updateFuncInner( | ... | @@ -5289,7 +5332,7 @@ fn updateFuncInner( |
| 5289 | error.WriteFailed => return nw.err.?, | 5332 | error.WriteFailed => return nw.err.?, |
| 5290 | else => |e| return e, | 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 | si.applyLocationRelocs(coff); | 5336 | si.applyLocationRelocs(coff); |
| 5294 | } | 5337 | } |
| 5295 | | 5338 | |
| ... | @@ -5533,6 +5576,7 @@ pub fn flush( | ... | @@ -5533,6 +5576,7 @@ pub fn flush( |
| 5533 | ) !void { | 5576 | ) !void { |
| 5534 | _ = arena; | 5577 | _ = arena; |
| 5535 | _ = prog_node; | 5578 | _ = prog_node; |
| | 5579 | const comp = coff.base.comp; |
| 5536 | | 5580 | |
| 5537 | // TODO: When https://github.com/ziglang/zig/issues/23617 is in, | 5581 | // TODO: When https://github.com/ziglang/zig/issues/23617 is in, |
| 5538 | // this should be set after updateExports instead | 5582 | // this should be set after updateExports instead |
| ... | @@ -5541,11 +5585,30 @@ pub fn flush( | ... | @@ -5541,11 +5585,30 @@ pub fn flush( |
| 5541 | while (try coff.resolve(tid)) {} | 5585 | while (try coff.resolve(tid)) {} |
| 5542 | while (try coff.idle(tid)) {} | 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 | if (coff.isImage()) | 5609 | if (coff.isImage()) |
| 5545 | try coff.reportUndefs(tid); | 5610 | try coff.reportUndefs(tid); |
| 5546 | | 5611 | |
| 5547 | const comp = coff.base.comp; | | |
| 5548 | | | |
| 5549 | // Implib generation should instead be done via building a MappedFile progressively | 5612 | // Implib generation should instead be done via building a MappedFile progressively |
| 5550 | if (comp.emit_implib) |implib_file| | 5613 | if (comp.emit_implib) |implib_file| |
| 5551 | coff.flushImplib(implib_file) catch |err| | 5614 | coff.flushImplib(implib_file) catch |err| |
| ... | @@ -5717,31 +5780,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -5717,31 +5780,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5717 | }; | 5780 | }; |
| 5718 | break :task; | 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 | if (coff.section_merge_pending_index < coff.section_merges.count()) return true; | 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,7 +5791,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5753 | if (coff.exports_complete and coff.pending_special_symbol != .none) return true; | 5791 | if (coff.exports_complete and coff.pending_special_symbol != .none) return true; |
| 5754 | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; | 5792 | for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true; |
| 5755 | if (coff.symbol_table.pending.count() > 0) return true; | 5793 | if (coff.symbol_table.pending.count() > 0) return true; |
| 5756 | if (coff.symbol_table.pending_shrink) return true; | | |
| 5757 | return false; | 5794 | return false; |
| 5758 | } | 5795 | } |
| 5759 | | 5796 | |
| ... | @@ -5922,7 +5959,7 @@ fn flushUav( | ... | @@ -5922,7 +5959,7 @@ fn flushUav( |
| 5922 | error.WriteFailed => return nw.err.?, | 5959 | error.WriteFailed => return nw.err.?, |
| 5923 | else => |e| return e, | 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 | si.applyLocationRelocs(coff); | 5963 | si.applyLocationRelocs(coff); |
| 5927 | } | 5964 | } |
| 5928 | | 5965 | |
| ... | @@ -6358,7 +6395,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { | ... | @@ -6358,7 +6395,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6358 | }); | 6395 | }); |
| 6359 | @memcpy(ni.slice(&coff.mf)[0..init.len], &init); | 6396 | @memcpy(ni.slice(&coff.mf)[0..init.len], &init); |
| 6360 | sym.ni = ni; | 6397 | sym.ni = ni; |
| 6361 | sym.setValue(.{ .size = init.len }); | 6398 | sym.extra.size = init.len; |
| 6362 | try coff.addReloc( | 6399 | try coff.addReloc( |
| 6363 | si, | 6400 | si, |
| 6364 | init.len - 4, | 6401 | init.len - 4, |
| ... | @@ -6539,7 +6576,7 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { | ... | @@ -6539,7 +6576,7 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6539 | error.WriteFailed => return nw.err.?, | 6576 | error.WriteFailed => return nw.err.?, |
| 6540 | else => |e| return e, | 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 | si.applyLocationRelocs(coff); | 6580 | si.applyLocationRelocs(coff); |
| 6544 | } | 6581 | } |
| 6545 | | 6582 | |
| ... | @@ -6556,13 +6593,15 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -6556,13 +6593,15 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6556 | .section_table, | 6593 | .section_table, |
| 6557 | .placeholder, | 6594 | .placeholder, |
| 6558 | => assert(!coff.isImage()), | 6595 | => assert(!coff.isImage()), |
| 6559 | .symbol_table => { | 6596 | .symbol_table, |
| 6560 | coff.targetStore( | 6597 | .string_table, |
| 6561 | &coff.headerPtr().pointer_to_symbol_table, | 6598 | => |_, tag| { |
| 6562 | @intCast(ni.location(&coff.mf).resolve(&coff.mf)[0]), | 6599 | if (tag == .symbol_table) |
| 6563 | ); | 6600 | coff.targetStore( |
| 6564 | }, | 6601 | &coff.headerPtr().pointer_to_symbol_table, |
| 6565 | .string_table => { | 6602 | @intCast(ni.location(&coff.mf).resolve(&coff.mf)[0]), |
| | 6603 | ); |
| | 6604 | |
| 6566 | if (!coff.symbol_table.pending_shrink) { | 6605 | if (!coff.symbol_table.pending_shrink) { |
| 6567 | const symbol_table_loc, const symbol_table_size = coff.symbol_table.ni.location(&coff.mf).resolve(&coff.mf); | 6606 | const symbol_table_loc, const symbol_table_size = coff.symbol_table.ni.location(&coff.mf).resolve(&coff.mf); |
| 6568 | const string_table_offset, _ = coff.symbol_table.strings_ni.location(&coff.mf).resolve(&coff.mf); | 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,10 +6861,8 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6822 | } | 6861 | } |
| 6823 | | 6862 | |
| 6824 | if (!coff.isImage()) { | 6863 | if (!coff.isImage()) { |
| 6825 | coff.targetStore( | 6864 | if (coff.symbolTableSectionAuxEntryPtr(si)) |aux_ptr| |
| 6826 | &coff.symbolTableSectionAuxEntryPtr(si).length, | 6865 | coff.targetStore(&aux_ptr.length, @intCast(size)); |
| 6827 | @intCast(size), | | |
| 6828 | ); | | |
| 6829 | } | 6866 | } |
| 6830 | }, | 6867 | }, |
| 6831 | .input_section => {}, | 6868 | .input_section => {}, |
| ... | @@ -6853,7 +6890,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -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 | .import_thunk, | 6895 | .import_thunk, |
| 6859 | .nav, | 6896 | .nav, |
| ... | @@ -7091,14 +7128,16 @@ fn updateExportsInner( | ... | @@ -7091,14 +7128,16 @@ fn updateExportsInner( |
| 7091 | const export_sym = export_si.get(coff); | 7128 | const export_sym = export_si.get(coff); |
| 7092 | export_sym.ni = exported_ni; | 7129 | export_sym.ni = exported_ni; |
| 7093 | export_sym.rva = exported_sym.rva; | 7130 | export_sym.rva = exported_sym.rva; |
| 7094 | export_sym.setValue(.{ .size = exported_sym.value.size }); | | |
| 7095 | export_sym.section_number = exported_sym.section_number; | 7131 | export_sym.section_number = exported_sym.section_number; |
| 7096 | defer export_si.applyTargetRelocs(coff, .none); | 7132 | defer export_si.applyTargetRelocs(coff, .none); |
| 7097 | | 7133 | |
| 7098 | const prev_alias_sym = prev_alias_si.get(coff); | 7134 | const prev_alias_sym = prev_alias_si.get(coff); |
| 7099 | assert(!prev_alias_sym.flags.has_alias); | 7135 | switch (prev_alias_sym.flags.extra_tag) { |
| 7100 | prev_alias_sym.extra = .{ .next_alias_si = export_si }; | 7136 | .size => export_sym.setExtra(.{ .size = prev_alias_sym.extra.size }), |
| 7101 | prev_alias_sym.flags.has_alias = true; | 7137 | else => unreachable, |
| | 7138 | } |
| | 7139 | |
| | 7140 | prev_alias_sym.setExtra(.{ .next_alias_si = export_si }); |
| 7102 | prev_alias_si = export_si; | 7141 | prev_alias_si = export_si; |
| 7103 | | 7142 | |
| 7104 | if (!coff.isImage()) continue; | 7143 | if (!coff.isImage()) continue; |
| ... | @@ -7237,7 +7276,7 @@ fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) !voi | ... | @@ -7237,7 +7276,7 @@ fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) !voi |
| 7237 | try w.print("{d:0>6}@{d:0>2} {x:08} n{d:0>8} | {s}\n", .{ | 7276 | try w.print("{d:0>6}@{d:0>2} {x:08} n{d:0>8} | {s}\n", .{ |
| 7238 | si, | 7277 | si, |
| 7239 | sym.section_number, | 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 | sym.ni, | 7280 | sym.ni, |
| 7242 | name.toSlice(coff), | 7281 | name.toSlice(coff), |
| 7243 | }); | 7282 | }); |
| ... | @@ -7251,11 +7290,11 @@ fn printSymbol( | ... | @@ -7251,11 +7290,11 @@ fn printSymbol( |
| 7251 | ) !void { | 7290 | ) !void { |
| 7252 | const sym = si.get(coff); | 7291 | const sym = si.get(coff); |
| 7253 | const node = coff.getNode(sym.ni); | 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 | si, | 7294 | si, |
| 7256 | sym.section_number, | 7295 | sym.section_number, |
| 7257 | if (sym.flags.value_tag == .size) | 7296 | if (sym.flags.extra_tag == .size) |
| 7258 | @as(u64, sym.value.size) | 7297 | @as(u64, sym.extra.size) |
| 7259 | else if (sym.ni != .none) | 7298 | else if (sym.ni != .none) |
| 7260 | sym.ni.location(&coff.mf).resolve(&coff.mf)[1] | 7299 | sym.ni.location(&coff.mf).resolve(&coff.mf)[1] |
| 7261 | else | 7300 | else |
| ... | @@ -7264,7 +7303,12 @@ fn printSymbol( | ... | @@ -7264,7 +7303,12 @@ fn printSymbol( |
| 7264 | .weak_alias_name => "an", | 7303 | .weak_alias_name => "an", |
| 7265 | .weak_alias_si => "as", | 7304 | .weak_alias_si => "as", |
| 7266 | .node_offset => "no", | 7305 | .node_offset => "no", |
| | 7306 | .sti => "st", |
| | 7307 | }, |
| | 7308 | switch (sym.flags.extra_tag) { |
| 7267 | .size => "sz", | 7309 | .size => "sz", |
| | 7310 | .isli => "li", |
| | 7311 | .next_alias_si => "na", |
| 7268 | }, | 7312 | }, |
| 7269 | switch (sym.flags.type) { | 7313 | switch (sym.flags.type) { |
| 7270 | .unknown => "u", | 7314 | .unknown => "u", |