| ... | ... | @@ -44,7 +44,7 @@ pending_default_libs: std.ArrayList(struct { |
| 44 | 44 | }), |
| 45 | 45 | alternate_names: std.AutoArrayHashMapUnmanaged(String, String), |
| 46 | 46 | input_objects: std.ArrayList(InputObject), |
| 47 | | input_symbols: std.ArrayList(Symbol.Index), |
| 47 | input_symbols: std.ArrayList(struct { si: Symbol.Index, name: String }), |
| 48 | 48 | input_sections: std.ArrayList(Node.InputSection), |
| 49 | 49 | input_section_pending_index: u32, |
| 50 | 50 | inputs_complete: bool, |
| ... | ... | @@ -300,6 +300,7 @@ pub const Node = union(enum) { |
| 300 | 300 | const InputSection = struct { |
| 301 | 301 | ioi: InputObject.Index, |
| 302 | 302 | si: Symbol.Index, |
| 303 | comdat_si: Symbol.Index, |
| 303 | 304 | file_location: MappedFile.Node.FileLocation, |
| 304 | 305 | first_li: Node.InputSection.LocalIndex, |
| 305 | 306 | crc: u32, |
| ... | ... | @@ -918,9 +919,13 @@ pub const Symbol = struct { |
| 918 | 919 | /// Relocations targeting this symbol |
| 919 | 920 | target_relocs: Reloc.Index, |
| 920 | 921 | section_number: SectionNumber, |
| 921 | | /// Only used when outputting objects |
| 922 | | sti: SymbolTable.Index, |
| 923 | 922 | gmi: Node.GlobalMapIndex, |
| 923 | extra: union { |
| 924 | /// Only valid when outputting objects |
| 925 | sti: SymbolTable.Index, |
| 926 | /// Only valid when .ni == .input_section and .value_tag == .node_offset |
| 927 | isli: Node.InputSection.LocalIndex, |
| 928 | }, |
| 924 | 929 | |
| 925 | 930 | pub const DllStorageClass = enum(u2) { |
| 926 | 931 | default, |
| ... | ... | @@ -1062,7 +1067,7 @@ pub const Symbol = struct { |
| 1062 | 1067 | |
| 1063 | 1068 | pub fn flushSymbolTableIndex(si: Symbol.Index, coff: *Coff) void { |
| 1064 | 1069 | const sym = si.get(coff); |
| 1065 | | const index = sym.sti.unwrap() orelse return; |
| 1070 | const index = sym.extra.sti.unwrap() orelse return; |
| 1066 | 1071 | var ri = sym.target_relocs; |
| 1067 | 1072 | while (ri != .none) { |
| 1068 | 1073 | const reloc = ri.get(coff); |
| ... | ... | @@ -2496,7 +2501,7 @@ pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) ?*align(2) std.c |
| 2496 | 2501 | } |
| 2497 | 2502 | |
| 2498 | 2503 | pub fn symbolTableSectionAuxEntryPtr(coff: *Coff, si: Symbol.Index) *align(2) std.coff.SectionDefinition { |
| 2499 | | const sti = si.get(coff).sti; |
| 2504 | const sti = si.get(coff).extra.sti; |
| 2500 | 2505 | const entry = symbolTableEntryPtr(coff, sti).?; |
| 2501 | 2506 | assert(entry.storage_class == .STATIC and entry.number_of_aux_symbols == 1); |
| 2502 | 2507 | return @ptrCast(@alignCast(symbolTableEntryStoragePtr(coff, sti.unwrap().? + 1))); |
| ... | ... | @@ -2546,8 +2551,8 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2546 | 2551 | .loc_relocs = .none, |
| 2547 | 2552 | .target_relocs = .none, |
| 2548 | 2553 | .section_number = .UNDEFINED, |
| 2549 | | .sti = .none, |
| 2550 | 2554 | .gmi = .none, |
| 2555 | .extra = .{ .sti = .none }, |
| 2551 | 2556 | }; |
| 2552 | 2557 | return @enumFromInt(coff.symbols.items.len); |
| 2553 | 2558 | } |
| ... | ... | @@ -2973,7 +2978,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 2973 | 2978 | const sym = si.get(coff); |
| 2974 | 2979 | assert(sym.ni != .none or sym.gmi != .none); |
| 2975 | 2980 | |
| 2976 | | const entry = coff.symbolTableEntryPtr(sym.sti) orelse entry: { |
| 2981 | const entry = coff.symbolTableEntryPtr(sym.extra.sti) orelse entry: { |
| 2977 | 2982 | var buf: [15]u8 = undefined; |
| 2978 | 2983 | const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType = |
| 2979 | 2984 | if (sym.gmi != .none) blk: { |
| ... | ... | @@ -3038,10 +3043,10 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3038 | 3043 | try coff.symbol_table.ni.resize(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf()); |
| 3039 | 3044 | |
| 3040 | 3045 | coff.targetStore(&coff.headerPtr().number_of_symbols, new_num_symbols); |
| 3041 | | sym.sti = .wrap(old_num_symbols); |
| 3046 | sym.extra = .{ .sti = .wrap(old_num_symbols) }; |
| 3042 | 3047 | si.flushSymbolTableIndex(coff); |
| 3043 | 3048 | |
| 3044 | | const entry = coff.symbolTableEntryPtr(sym.sti).?; |
| 3049 | const entry = coff.symbolTableEntryPtr(sym.extra.sti).?; |
| 3045 | 3050 | symbol_name.store(coff, &entry.name); |
| 3046 | 3051 | |
| 3047 | 3052 | entry.section_number = @enumFromInt(@intFromEnum(sym.section_number)); |
| ... | ... | @@ -3071,7 +3076,7 @@ fn flushSymbolTableEntry(coff: *Coff, si: Symbol.Index, pt: Zcu.PerThread) !void |
| 3071 | 3076 | }, |
| 3072 | 3077 | }); |
| 3073 | 3078 | |
| 3074 | | log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sym.sti }); |
| 3079 | log.debug("flushSymbolTableEntry({d}) = {d}", .{ si, sym.extra.sti }); |
| 3075 | 3080 | } |
| 3076 | 3081 | |
| 3077 | 3082 | fn flushInputMember(coff: *Coff, iami: InputArchive.Member.Index) !void { |
| ... | ... | @@ -3467,8 +3472,8 @@ pub fn addReloc( |
| 3467 | 3472 | else => |loc_sn| sri: { |
| 3468 | 3473 | // The target may not have a node yet, or it could be an extern that will never |
| 3469 | 3474 | // have a node. In that case, flushGlobal will create the symbol table entry. |
| 3470 | | const sti: SymbolTable.Index = if (target.sti != .none) |
| 3471 | | target.sti |
| 3475 | const sti: SymbolTable.Index = if (target.extra.sti != .none) |
| 3476 | target.extra.sti |
| 3472 | 3477 | else if (target.ni != .none) sti: { |
| 3473 | 3478 | try coff.pendingSymbolTableEntry(target_si); |
| 3474 | 3479 | break :sti .none; |
| ... | ... | @@ -4381,6 +4386,10 @@ fn loadObject( |
| 4381 | 4386 | }, |
| 4382 | 4387 | .first_li = @enumFromInt(coff.input_symbols.items.len), |
| 4383 | 4388 | .crc = section.comdat_crc, |
| 4389 | .comdat_si = if (section.comdat_psi.unwrap()) |psi| |
| 4390 | pending_symbols.values()[psi].si |
| 4391 | else |
| 4392 | .null, |
| 4384 | 4393 | }; |
| 4385 | 4394 | |
| 4386 | 4395 | log.debug( |
| ... | ... | @@ -4489,6 +4498,9 @@ fn loadObject( |
| 4489 | 4498 | .weak_external_aux, |
| 4490 | 4499 | => unreachable, |
| 4491 | 4500 | } |
| 4501 | |
| 4502 | if (section.comdat_psi.unwrap() == @as(u32, @intCast(i))) |
| 4503 | coff.getNode(section.si.get(coff).ni).input_section.inputSection(coff).comdat_si = symbol.si; |
| 4492 | 4504 | } |
| 4493 | 4505 | |
| 4494 | 4506 | if (symbol.weak_external_psi.unwrap()) |weak_external_i| { |
| ... | ... | @@ -4610,7 +4622,11 @@ fn loadObject( |
| 4610 | 4622 | |
| 4611 | 4623 | if (include_section) { |
| 4612 | 4624 | assert(coff.getNode(symbol.si.get(coff).ni) == .input_section); |
| 4613 | | coff.input_symbols.addOneAssumeCapacity().* = symbol.si; |
| 4625 | symbol.si.get(coff).extra = .{ .isli = @enumFromInt(coff.input_symbols.items.len) }; |
| 4626 | coff.input_symbols.addOneAssumeCapacity().* = .{ |
| 4627 | .si = symbol.si, |
| 4628 | .name = symbol.name, |
| 4629 | }; |
| 4614 | 4630 | } |
| 4615 | 4631 | } |
| 4616 | 4632 | } |
| ... | ... | @@ -5450,11 +5466,30 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5450 | 5466 | .input_section => |isi| { |
| 5451 | 5467 | const other_ioi = isi.input(coff); |
| 5452 | 5468 | if (loc_sym.gmi == .none) { |
| 5453 | | // TODO: We could report non-global names here if we intern them in loadObject |
| 5454 | | err.addNote("referenced by input '{f}{f}'", .{ |
| 5455 | | other_ioi.path(coff).fmtEscapeString(), |
| 5456 | | fmtMemberNameString(other_ioi.memberName(coff)), |
| 5457 | | }); |
| 5469 | const section = isi.inputSection(coff); |
| 5470 | const section_name = coff.getNode(loc_sym.ni.parent(&coff.mf)) |
| 5471 | .object_section.name(coff).toSlice(coff); |
| 5472 | |
| 5473 | if (section.comdat_si != .null) { |
| 5474 | const comdat_sym = section.comdat_si.get(coff); |
| 5475 | const comdat_name = if (comdat_sym.gmi != .none) |
| 5476 | comdat_sym.gmi.globalName(coff).name.toSlice(coff) |
| 5477 | else |
| 5478 | coff.input_symbols.items[@intFromEnum(comdat_sym.extra.isli)].name.toSlice(coff); |
| 5479 | |
| 5480 | err.addNote("referenced by input COMDAT section '{s}={s}' '{f}{f}'", .{ |
| 5481 | section_name, |
| 5482 | comdat_name, |
| 5483 | other_ioi.path(coff).fmtEscapeString(), |
| 5484 | fmtMemberNameString(other_ioi.memberName(coff)), |
| 5485 | }); |
| 5486 | } else { |
| 5487 | err.addNote("referenced by input section '{s}' '{f}{f}'", .{ |
| 5488 | section_name, |
| 5489 | other_ioi.path(coff).fmtEscapeString(), |
| 5490 | fmtMemberNameString(other_ioi.memberName(coff)), |
| 5491 | }); |
| 5492 | } |
| 5458 | 5493 | } else { |
| 5459 | 5494 | err.addNote("referenced by input symbol '{s}' from '{f}{f}'", .{ |
| 5460 | 5495 | loc_sym.gmi.globalName(coff).name.toSlice(coff), |
| ... | ... | @@ -6558,9 +6593,9 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6558 | 6593 | }, |
| 6559 | 6594 | .input_section => |isi| { |
| 6560 | 6595 | isi.symbol(coff).flushMoved(coff); |
| 6561 | | for (coff.input_symbols.items[@intFromEnum(isi.firstSymbol(coff))..]) |si| { |
| 6562 | | if (si.get(coff).ni != ni) break; |
| 6563 | | si.flushMoved(coff); |
| 6596 | for (coff.input_symbols.items[@intFromEnum(isi.firstSymbol(coff))..]) |input_symbol| { |
| 6597 | if (input_symbol.si.get(coff).ni != ni) break; |
| 6598 | input_symbol.si.flushMoved(coff); |
| 6564 | 6599 | } |
| 6565 | 6600 | }, |
| 6566 | 6601 | .import_directory_table => coff.targetStore( |
| ... | ... | @@ -7165,7 +7200,7 @@ pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpRe |
| 7165 | 7200 | try coff.printSection(w, name, sec.si); |
| 7166 | 7201 | try w.writeAll("Symbol table:\n"); |
| 7167 | 7202 | for (1..coff.symbols.items.len) |si| |
| 7168 | | try coff.printSymbol(w, @enumFromInt(si)); |
| 7203 | try coff.printSymbol(w, tid, @enumFromInt(si)); |
| 7169 | 7204 | |
| 7170 | 7205 | return .enabled; |
| 7171 | 7206 | } |
| ... | ... | @@ -7183,10 +7218,15 @@ fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) !voi |
| 7183 | 7218 | }); |
| 7184 | 7219 | } |
| 7185 | 7220 | |
| 7186 | | fn printSymbol(coff: *Coff, w: *Io.Writer, si: Symbol.Index) !void { |
| 7221 | fn printSymbol( |
| 7222 | coff: *Coff, |
| 7223 | w: *Io.Writer, |
| 7224 | tid: Zcu.PerThread.Id, |
| 7225 | si: Symbol.Index, |
| 7226 | ) !void { |
| 7187 | 7227 | const sym = si.get(coff); |
| 7188 | 7228 | const node = coff.getNode(sym.ni); |
| 7189 | | try w.print("{d:0>6}@{d:0>2} {x:08} {s} n{d:0>8}+{x:08}:{t: <26} | {x:08} | {f}\n", .{ |
| 7229 | try w.print("{d:0>6}@{d:0>2} {x:08} {s} {s} n{d:0>8}+{x:08}:{t: <26} | {x:08} ", .{ |
| 7190 | 7230 | si, |
| 7191 | 7231 | sym.section_number, |
| 7192 | 7232 | if (sym.flags.value_tag == .size) |
| ... | ... | @@ -7195,6 +7235,12 @@ fn printSymbol(coff: *Coff, w: *Io.Writer, si: Symbol.Index) !void { |
| 7195 | 7235 | sym.ni.location(&coff.mf).resolve(&coff.mf)[1] |
| 7196 | 7236 | else |
| 7197 | 7237 | 0, |
| 7238 | switch (sym.flags.value_tag) { |
| 7239 | .alias_name => "an", |
| 7240 | .alias_si => "as", |
| 7241 | .node_offset => "no", |
| 7242 | .size => "sz", |
| 7243 | }, |
| 7198 | 7244 | switch (sym.flags.type) { |
| 7199 | 7245 | .unknown => "u", |
| 7200 | 7246 | .code => "c", |
| ... | ... | @@ -7204,8 +7250,15 @@ fn printSymbol(coff: *Coff, w: *Io.Writer, si: Symbol.Index) !void { |
| 7204 | 7250 | if (sym.flags.value_tag == .node_offset) sym.value.node_offset else 0, |
| 7205 | 7251 | node, |
| 7206 | 7252 | sym.rva, |
| 7207 | | fmtGlobalName(coff, sym.gmi), |
| 7208 | 7253 | }); |
| 7254 | |
| 7255 | if (sym.gmi != .none) { |
| 7256 | try w.print("G {f}\n", .{fmtGlobalName(coff, sym.gmi)}); |
| 7257 | } else { |
| 7258 | try w.writeAll("| "); |
| 7259 | try coff.printNodeName(w, tid, node); |
| 7260 | try w.writeByte('\n'); |
| 7261 | } |
| 7209 | 7262 | } |
| 7210 | 7263 | |
| 7211 | 7264 | const FmtGlobalName = struct { coff: *Coff, gmi: Node.GlobalMapIndex }; |
| ... | ... | @@ -7222,16 +7275,12 @@ fn globalNameEscape(data: FmtGlobalName, w: *std.Io.Writer) std.Io.Writer.Error! |
| 7222 | 7275 | try w.print("({s})", .{lib_name.toSlice(data.coff)}); |
| 7223 | 7276 | } |
| 7224 | 7277 | |
| 7225 | | pub fn printNode( |
| 7278 | fn printNodeName( |
| 7226 | 7279 | coff: *Coff, |
| 7280 | w: *std.Io.Writer, |
| 7227 | 7281 | tid: Zcu.PerThread.Id, |
| 7228 | | w: *Io.Writer, |
| 7229 | | ni: MappedFile.Node.Index, |
| 7230 | | indent: usize, |
| 7282 | node: Node, |
| 7231 | 7283 | ) !void { |
| 7232 | | const node = coff.getNode(ni); |
| 7233 | | try w.splatByteAll(' ', indent); |
| 7234 | | try w.writeAll(@tagName(node)); |
| 7235 | 7284 | switch (node) { |
| 7236 | 7285 | else => {}, |
| 7237 | 7286 | .image_section => |si| try w.print("({s})", .{ |
| ... | ... | @@ -7239,11 +7288,23 @@ pub fn printNode( |
| 7239 | 7288 | }), |
| 7240 | 7289 | .input_section => |isi| { |
| 7241 | 7290 | const ioi = isi.input(coff); |
| 7242 | | try w.print("({f}{f}, {s})", .{ |
| 7291 | const is = isi.inputSection(coff); |
| 7292 | // TODO: Use only filename from these paths, they are long |
| 7293 | try w.print("({f}{f}, {s}", .{ |
| 7243 | 7294 | ioi.path(coff).fmtEscapeString(), |
| 7244 | 7295 | fmtMemberNameString(ioi.memberName(coff)), |
| 7245 | | coff.getNode(isi.symbol(coff).node(coff).parent(&coff.mf)).object_section.name(coff).toSlice(coff), |
| 7296 | coff.getNode(is.si.node(coff).parent(&coff.mf)).object_section.name(coff).toSlice(coff), |
| 7246 | 7297 | }); |
| 7298 | if (is.comdat_si != .null) { |
| 7299 | const comdat_sym = is.comdat_si.get(coff); |
| 7300 | const comdat_name = if (comdat_sym.gmi != .none) |
| 7301 | comdat_sym.gmi.globalName(coff).name.toSlice(coff) |
| 7302 | else |
| 7303 | coff.input_symbols.items[@intFromEnum(comdat_sym.extra.isli)].name.toSlice(coff); |
| 7304 | |
| 7305 | try w.print("={s}", .{comdat_name}); |
| 7306 | } |
| 7307 | try w.writeAll(")"); |
| 7247 | 7308 | }, |
| 7248 | 7309 | .import_lookup_table, |
| 7249 | 7310 | .import_address_table, |
| ... | ... | @@ -7284,6 +7345,19 @@ pub fn printNode( |
| 7284 | 7345 | }), |
| 7285 | 7346 | }), |
| 7286 | 7347 | } |
| 7348 | } |
| 7349 | |
| 7350 | pub fn printNode( |
| 7351 | coff: *Coff, |
| 7352 | tid: Zcu.PerThread.Id, |
| 7353 | w: *Io.Writer, |
| 7354 | ni: MappedFile.Node.Index, |
| 7355 | indent: usize, |
| 7356 | ) !void { |
| 7357 | const node = coff.getNode(ni); |
| 7358 | try w.splatByteAll(' ', indent); |
| 7359 | try w.writeAll(@tagName(node)); |
| 7360 | try coff.printNodeName(w, tid, node); |
| 7287 | 7361 | { |
| 7288 | 7362 | const mf_node = &coff.mf.nodes.items[@intFromEnum(ni)]; |
| 7289 | 7363 | const off, const size = mf_node.location().resolve(&coff.mf); |