| ... | @@ -912,7 +912,8 @@ pub const Symbol = struct { | ... | @@ -912,7 +912,8 @@ pub const Symbol = struct { |
| 912 | dll_storage_class: DllStorageClass, | 912 | dll_storage_class: DllStorageClass, |
| 913 | // Only defined for .alias_si and .alias_name | 913 | // Only defined for .alias_si and .alias_name |
| 914 | weak_external_strat: WeakExternalStrat, | 914 | weak_external_strat: WeakExternalStrat, |
| 915 | _: u8 = 0, | 915 | has_exports: bool, |
| | 916 | _: u7 = 0, |
| 916 | }, | 917 | }, |
| 917 | /// Relocations contained within this symbol | 918 | /// Relocations contained within this symbol |
| 918 | loc_relocs: Reloc.Index, | 919 | loc_relocs: Reloc.Index, |
| ... | @@ -924,7 +925,11 @@ pub const Symbol = struct { | ... | @@ -924,7 +925,11 @@ pub const Symbol = struct { |
| 924 | /// Only valid when outputting objects | 925 | /// Only valid when outputting objects |
| 925 | sti: SymbolTable.Index, | 926 | sti: SymbolTable.Index, |
| 926 | /// Only valid when .ni == .input_section and .value_tag == .node_offset | 927 | /// Only valid when .ni == .input_section and .value_tag == .node_offset |
| | 928 | /// TODO: This is only used for name lookups, could just be String? |
| 927 | isli: Node.InputSection.LocalIndex, | 929 | isli: Node.InputSection.LocalIndex, |
| | 930 | /// Only valid if flags.has_exports is set. The first in a contiguous |
| | 931 | /// list of symbols that are exports of this symbol. |
| | 932 | first_export_si: Symbol.Index, |
| 928 | }, | 933 | }, |
| 929 | | 934 | |
| 930 | pub const DllStorageClass = enum(u2) { | 935 | pub const DllStorageClass = enum(u2) { |
| ... | @@ -1063,6 +1068,15 @@ pub const Symbol = struct { | ... | @@ -1063,6 +1068,15 @@ pub const Symbol = struct { |
| 1063 | sym.rva = coff.computeNodeRva(sym.ni) + sym.nodeOffset(coff); | 1068 | sym.rva = coff.computeNodeRva(sym.ni) + sym.nodeOffset(coff); |
| 1064 | si.applyLocationRelocs(coff); | 1069 | si.applyLocationRelocs(coff); |
| 1065 | si.applyTargetRelocs(coff, .none); | 1070 | si.applyTargetRelocs(coff, .none); |
| | 1071 | |
| | 1072 | if (sym.flags.has_exports) { |
| | 1073 | for (coff.symbols.items[@intFromEnum(sym.extra.first_export_si)..]) |*export_sym| { |
| | 1074 | if (export_sym.ni != sym.ni) break; |
| | 1075 | export_sym.rva = sym.rva; |
| | 1076 | const export_si: Symbol.Index = @enumFromInt(export_sym - coff.symbols.items.ptr); |
| | 1077 | export_si.applyTargetRelocs(coff, .none); |
| | 1078 | } |
| | 1079 | } |
| 1066 | } | 1080 | } |
| 1067 | | 1081 | |
| 1068 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { | 1082 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { |
| ... | @@ -2547,6 +2561,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { | ... | @@ -2547,6 +2561,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2547 | .type = .unknown, | 2561 | .type = .unknown, |
| 2548 | .dll_storage_class = .default, | 2562 | .dll_storage_class = .default, |
| 2549 | .weak_external_strat = undefined, | 2563 | .weak_external_strat = undefined, |
| | 2564 | .has_exports = false, |
| 2550 | }, | 2565 | }, |
| 2551 | .loc_relocs = .none, | 2566 | .loc_relocs = .none, |
| 2552 | .target_relocs = .none, | 2567 | .target_relocs = .none, |
| ... | @@ -7063,9 +7078,14 @@ fn updateExportsInner( | ... | @@ -7063,9 +7078,14 @@ fn updateExportsInner( |
| 7063 | const machine = coff.targetLoad(&coff.headerPtr().machine); | 7078 | const machine = coff.targetLoad(&coff.headerPtr().machine); |
| 7064 | const exported_ni = exported_si.node(coff); | 7079 | const exported_ni = exported_si.node(coff); |
| 7065 | const exported_sym = exported_si.get(coff); | 7080 | const exported_sym = exported_si.get(coff); |
| | 7081 | exported_sym.extra = .{ .first_export_si = @enumFromInt(coff.symbols.items.len) }; |
| | 7082 | exported_sym.flags.has_exports = true; |
| | 7083 | |
| 7066 | for (export_indices) |export_index| { | 7084 | for (export_indices) |export_index| { |
| 7067 | const @"export" = export_index.ptr(zcu); | 7085 | const @"export" = export_index.ptr(zcu); |
| 7068 | const name = @"export".opts.name.toSlice(ip); | 7086 | const name = @"export".opts.name.toSlice(ip); |
| | 7087 | // TODO: Add an errMsg if this conflicts with an existing global from an input |
| | 7088 | // first_export_si relies on this being a new symbol. |
| 7069 | const export_si = try coff.globalSymbol(.{ | 7089 | const export_si = try coff.globalSymbol(.{ |
| 7070 | .name = name, | 7090 | .name = name, |
| 7071 | .lib_name = null, | 7091 | .lib_name = null, |