| ... | ... | @@ -64,7 +64,7 @@ object_section_table: std.array_hash_map.Auto(String, Symbol.Index), |
| 64 | 64 | section_merges: std.array_hash_map.Auto(String, String), |
| 65 | 65 | section_merge_pending_index: u32, |
| 66 | 66 | symbols: std.ArrayList(Symbol), |
| 67 | | globals: std.array_hash_map.Auto(GlobalName, Symbol.Index), |
| 67 | globals: std.array_hash_map.Auto(String, Global), |
| 68 | 68 | global_pending_index: u32, |
| 69 | 69 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, Symbol.Index), |
| 70 | 70 | uavs: std.array_hash_map.Auto(InternPool.Index, Symbol.Index), |
| ... | ... | @@ -268,12 +268,16 @@ pub const Node = union(enum) { |
| 268 | 268 | }; |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | | pub fn globalName(gmi: GlobalMapIndex, coff: *const Coff) GlobalName { |
| 271 | pub fn name(gmi: GlobalMapIndex, coff: *const Coff) String { |
| 272 | 272 | return coff.globals.keys()[gmi.unwrap().?]; |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | pub fn symbol(gmi: GlobalMapIndex, coff: *const Coff) Symbol.Index { |
| 276 | | return coff.globals.values()[gmi.unwrap().?]; |
| 276 | return coff.globals.values()[gmi.unwrap().?].si; |
| 277 | } |
| 278 | |
| 279 | pub fn libName(gmi: GlobalMapIndex, coff: *const Coff) String.Optional { |
| 280 | return coff.globals.values()[gmi.unwrap().?].lib_name; |
| 277 | 281 | } |
| 278 | 282 | }; |
| 279 | 283 | |
| ... | ... | @@ -335,6 +339,10 @@ pub const Node = union(enum) { |
| 335 | 339 | |
| 336 | 340 | const LocalIndex = enum(u32) { |
| 337 | 341 | _, |
| 342 | |
| 343 | pub fn name(isli: LocalIndex, coff: *const Coff) String { |
| 344 | return coff.input_symbols.items[@intFromEnum(isli)].name; |
| 345 | } |
| 338 | 346 | }; |
| 339 | 347 | }; |
| 340 | 348 | |
| ... | ... | @@ -847,12 +855,15 @@ pub const Section = struct { |
| 847 | 855 | ) ?*align(2) std.coff.Relocation { |
| 848 | 856 | if (sri == .none) return null; |
| 849 | 857 | const table_slice = sn.section(coff).relocation_table_ni.slice(&coff.mf); |
| 850 | | return @ptrCast(@alignCast(&table_slice[sri.unwrap().? * std.coff.Relocation.sizeOf()])); |
| 858 | return @ptrCast(@alignCast(&table_slice[@as(u32, sri.unwrap().?) * std.coff.Relocation.sizeOf()])); |
| 851 | 859 | } |
| 852 | 860 | }; |
| 853 | 861 | }; |
| 854 | 862 | |
| 855 | | pub const GlobalName = struct { name: String, lib_name: String.Optional }; |
| 863 | pub const Global = struct { |
| 864 | si: Symbol.Index, |
| 865 | lib_name: String.Optional, |
| 866 | }; |
| 856 | 867 | |
| 857 | 868 | pub const WeakExternalStrat = enum(u3) { |
| 858 | 869 | none, |
| ... | ... | @@ -1332,7 +1343,7 @@ pub const Reloc = extern struct { |
| 1332 | 1343 | // so that this function doesn't return an err |
| 1333 | 1344 | else => |kind| return coff.base.comp.link_diags.fail( |
| 1334 | 1345 | "absolute symbol '{s}' targeted by invalid relocation type: {t}", |
| 1335 | | .{ target_sym.gmi.globalName(coff).name.toSlice(coff), kind }, |
| 1346 | .{ target_sym.gmi.name(coff).toSlice(coff), kind }, |
| 1336 | 1347 | ), |
| 1337 | 1348 | .ABSOLUTE => {}, |
| 1338 | 1349 | .ADDR64 => std.mem.writeInt( |
| ... | ... | @@ -1351,7 +1362,7 @@ pub const Reloc = extern struct { |
| 1351 | 1362 | .I386 => switch (reloc.type.I386) { |
| 1352 | 1363 | else => |kind| return coff.base.comp.link_diags.fail( |
| 1353 | 1364 | "absolute symbol '{s}' targeted by invalid relocation type: {t}", |
| 1354 | | .{ target_sym.gmi.globalName(coff).name.toSlice(coff), kind }, |
| 1365 | .{ target_sym.gmi.name(coff).toSlice(coff), kind }, |
| 1355 | 1366 | ), |
| 1356 | 1367 | .ABSOLUTE => {}, |
| 1357 | 1368 | .DIR16 => std.mem.writeInt( |
| ... | ... | @@ -2767,12 +2778,12 @@ const GlobalOptions = struct { |
| 2767 | 2778 | fn getOrPutGlobalSymbol( |
| 2768 | 2779 | coff: *Coff, |
| 2769 | 2780 | opts: GlobalOptions, |
| 2770 | | ) !std.array_hash_map.Auto(GlobalName, Symbol.Index).GetOrPutResult { |
| 2781 | ) !std.array_hash_map.Auto(String, Global).GetOrPutResult { |
| 2771 | 2782 | const comp = coff.base.comp; |
| 2772 | 2783 | const gpa = comp.gpa; |
| 2773 | 2784 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 2774 | 2785 | |
| 2775 | | const lib_name = if (opts.lib_name) |lib_name| lib_name: { |
| 2786 | const lib_name: String.Optional = if (opts.lib_name) |lib_name| lib_name: { |
| 2776 | 2787 | const is_libc = std.zig.target.isLibCLibName(&comp.root_mod.resolved_target.result, lib_name); |
| 2777 | 2788 | if (is_libc) { |
| 2778 | 2789 | // This is guaranteed by Sema.handleExternLibName |
| ... | ... | @@ -2781,23 +2792,23 @@ fn getOrPutGlobalSymbol( |
| 2781 | 2792 | // TODO: The user has requested this symbol come from libc, but this logic allows |
| 2782 | 2793 | // it to come from anywhere. We need to know what inputs are libc inputs, |
| 2783 | 2794 | // and set a flag to only search them for this symbol. |
| 2784 | | break :lib_name null; |
| 2795 | break :lib_name .none; |
| 2785 | 2796 | } |
| 2786 | 2797 | |
| 2787 | | break :lib_name lib_name; |
| 2788 | | } else null; |
| 2798 | break :lib_name (try coff.getOrPutString(lib_name)).toOptional(); |
| 2799 | } else .none; |
| 2789 | 2800 | |
| 2790 | | const sym_gop = try coff.globals.getOrPut(gpa, .{ |
| 2791 | | .name = try coff.getOrPutString(opts.name), |
| 2792 | | .lib_name = try coff.getOrPutOptionalString(lib_name), |
| 2793 | | }); |
| 2801 | const sym_gop = try coff.globals.getOrPut(gpa, try coff.getOrPutString(opts.name)); |
| 2794 | 2802 | if (!sym_gop.found_existing) { |
| 2795 | 2803 | const si = coff.addSymbolAssumeCapacity(); |
| 2796 | 2804 | const sym = si.get(coff); |
| 2797 | 2805 | sym.gmi = .wrap(@intCast(sym_gop.index)); |
| 2798 | 2806 | sym.flags.type = opts.type; |
| 2799 | 2807 | sym.flags.dll_storage_class = opts.dll_storage_class; |
| 2800 | | sym_gop.value_ptr.* = si; |
| 2808 | sym_gop.value_ptr.* = .{ |
| 2809 | .si = si, |
| 2810 | .lib_name = lib_name, |
| 2811 | }; |
| 2801 | 2812 | coff.synth_prog_node.increaseEstimatedTotalItems(1); |
| 2802 | 2813 | |
| 2803 | 2814 | log.debug("globalSymbol({s}, {?s}) = {d}", .{ opts.name, opts.lib_name, si }); |
| ... | ... | @@ -2807,16 +2818,15 @@ fn getOrPutGlobalSymbol( |
| 2807 | 2818 | } |
| 2808 | 2819 | |
| 2809 | 2820 | fn getDefinedGlobal(coff: *Coff, name: []const u8) Symbol.Index { |
| 2810 | | if (coff.globals.get(.{ |
| 2811 | | .name = coff.getString(name).unwrap() orelse return .null, |
| 2812 | | .lib_name = .none, |
| 2813 | | })) |si| if (si.get(coff).ni != .none) return si; |
| 2821 | if (coff.globals.get( |
| 2822 | coff.getString(name).unwrap() orelse return .null, |
| 2823 | )) |global| if (global.si.get(coff).ni != .none) return global.si; |
| 2814 | 2824 | return .null; |
| 2815 | 2825 | } |
| 2816 | 2826 | |
| 2817 | 2827 | pub fn globalSymbol(coff: *Coff, opts: GlobalOptions) !Symbol.Index { |
| 2818 | 2828 | const gop = try coff.getOrPutGlobalSymbol(opts); |
| 2819 | | return gop.value_ptr.*; |
| 2829 | return gop.value_ptr.si; |
| 2820 | 2830 | } |
| 2821 | 2831 | |
| 2822 | 2832 | pub fn pendingSymbolTableEntry(coff: *Coff, si: Symbol.Index) !void { |
| ... | ... | @@ -3121,9 +3131,9 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32, pt: Zcu.PerThread) !void { |
| 3121 | 3131 | var buf: [15]u8 = undefined; |
| 3122 | 3132 | const symbol_name, const num_aux_symbols: u8, const complex_type: std.coff.ComplexType = |
| 3123 | 3133 | if (sym.gmi != .none) blk: { |
| 3124 | | const gn = sym.gmi.globalName(coff); |
| 3134 | const name = sym.gmi.name(coff); |
| 3125 | 3135 | break :blk .{ |
| 3126 | | try coff.getOrPutSymbolName(gn.name.toSlice(coff), gn.name), |
| 3136 | try coff.getOrPutSymbolName(name.toSlice(coff), name), |
| 3127 | 3137 | @intFromBool(sym.flags.weak_external_strat != .none), |
| 3128 | 3138 | if (Symbol.Index.text.get(coff).section_number == sym.section_number) |
| 3129 | 3139 | .FUNCTION |
| ... | ... | @@ -3735,7 +3745,7 @@ fn addRelocAssumeCapacity( |
| 3735 | 3745 | const header = loc_sn.header(coff); |
| 3736 | 3746 | const old_num_relocations = coff.targetLoad(&header.number_of_relocations); |
| 3737 | 3747 | const new_num_relocations = old_num_relocations + 1; |
| 3738 | | const new_size = new_num_relocations * std.coff.Relocation.sizeOf(); |
| 3748 | const new_size = @as(u32, new_num_relocations) * std.coff.Relocation.sizeOf(); |
| 3739 | 3749 | |
| 3740 | 3750 | coff.targetStore(&header.number_of_relocations, new_num_relocations); |
| 3741 | 3751 | if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff).sti(coff))) |aux_ptr| |
| ... | ... | @@ -4529,17 +4539,16 @@ fn loadObject( |
| 4529 | 4539 | .external => { |
| 4530 | 4540 | const global_gop = try coff.getOrPutGlobalSymbol(.{ |
| 4531 | 4541 | .name = symbol.name.toSlice(coff), |
| 4532 | | .lib_name = null, |
| 4533 | 4542 | }); |
| 4534 | 4543 | |
| 4535 | 4544 | // TODO: What if the same symbol is incorrectly defined twice in this obj? |
| 4536 | 4545 | // Would need to mark this global as pending, or notice it later when .ni != none |
| 4537 | | if (!global_gop.found_existing or global_gop.value_ptr.get(coff).ni == .none) { |
| 4538 | | symbol.si = global_gop.value_ptr.*; |
| 4546 | if (!global_gop.found_existing or global_gop.value_ptr.si.get(coff).ni == .none) { |
| 4547 | symbol.si = global_gop.value_ptr.si; |
| 4539 | 4548 | break :comdat .include; |
| 4540 | 4549 | } |
| 4541 | 4550 | |
| 4542 | | break :existing global_gop.value_ptr.*; |
| 4551 | break :existing global_gop.value_ptr.si; |
| 4543 | 4552 | }, |
| 4544 | 4553 | }; |
| 4545 | 4554 | |
| ... | ... | @@ -4736,7 +4745,7 @@ fn loadObject( |
| 4736 | 4745 | }, |
| 4737 | 4746 | .weak_external => |alias_index| { |
| 4738 | 4747 | const global_gop = try coff.getOrPutGlobalSymbol(.{ .name = symbol.name.toSlice(coff) }); |
| 4739 | | symbol.si = global_gop.value_ptr.*; |
| 4748 | symbol.si = global_gop.value_ptr.si; |
| 4740 | 4749 | if (!global_gop.found_existing or symbol.si.get(coff).ni == .none) { |
| 4741 | 4750 | const sym = symbol.si.get(coff); |
| 4742 | 4751 | const alias = pending_symbols.getPtr(alias_index) orelse |
| ... | ... | @@ -4775,9 +4784,16 @@ fn loadObject( |
| 4775 | 4784 | }, |
| 4776 | 4785 | .external => |value| { |
| 4777 | 4786 | const global_gop = try coff.getOrPutGlobalSymbol(.{ .name = symbol.name.toSlice(coff) }); |
| 4778 | | symbol.si = global_gop.value_ptr.*; |
| 4787 | symbol.si = global_gop.value_ptr.si; |
| 4779 | 4788 | if (global_gop.found_existing) |
| 4780 | | return coff.failMultipleDefinitions(path, member_name, symbol.name, index, global_gop.value_ptr.*, .none); |
| 4789 | return coff.failMultipleDefinitions( |
| 4790 | path, |
| 4791 | member_name, |
| 4792 | symbol.name, |
| 4793 | index, |
| 4794 | global_gop.value_ptr.si, |
| 4795 | .none, |
| 4796 | ); |
| 4781 | 4797 | break :sym value; |
| 4782 | 4798 | }, |
| 4783 | 4799 | else => unreachable, |
| ... | ... | @@ -4804,11 +4820,18 @@ fn loadObject( |
| 4804 | 4820 | .external => { |
| 4805 | 4821 | assert(index != section.comdat_psi.unwrap()); |
| 4806 | 4822 | const global_gop = try coff.getOrPutGlobalSymbol(.{ .name = symbol.name.toSlice(coff) }); |
| 4807 | | symbol.si = global_gop.value_ptr.*; |
| 4823 | symbol.si = global_gop.value_ptr.si; |
| 4808 | 4824 | |
| 4809 | 4825 | const sym = symbol.si.get(coff); |
| 4810 | 4826 | if (global_gop.found_existing and sym.ni != .none) |
| 4811 | | return coff.failMultipleDefinitions(path, member_name, symbol.name, index, global_gop.value_ptr.*, .none); |
| 4827 | return coff.failMultipleDefinitions( |
| 4828 | path, |
| 4829 | member_name, |
| 4830 | symbol.name, |
| 4831 | index, |
| 4832 | global_gop.value_ptr.si, |
| 4833 | .none, |
| 4834 | ); |
| 4812 | 4835 | }, |
| 4813 | 4836 | .weak_external, |
| 4814 | 4837 | .weak_external_aux, |
| ... | ... | @@ -4881,7 +4904,7 @@ fn loadObject( |
| 4881 | 4904 | switch (symbol.value) { |
| 4882 | 4905 | .external => |size| { |
| 4883 | 4906 | const global_gop = try coff.getOrPutGlobalSymbol(.{ .name = symbol.name.toSlice(coff) }); |
| 4884 | | symbol.si = global_gop.value_ptr.*; |
| 4907 | symbol.si = global_gop.value_ptr.si; |
| 4885 | 4908 | if (!global_gop.found_existing or symbol.si.get(coff).ni == .none) { |
| 4886 | 4909 | const sym = symbol.si.get(coff); |
| 4887 | 4910 | sym.setExtra(.{ .size = @max(sym.size(), size) }); |
| ... | ... | @@ -5743,7 +5766,9 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5743 | 5766 | num_full_notes + @intFromBool(num_unique_references > max_notes), |
| 5744 | 5767 | ); |
| 5745 | 5768 | const target_sym = target.get(coff); |
| 5746 | | try err.addMsg("undefined symbol: {s}", .{target_sym.gmi.globalName(coff).name.toSlice(coff)}); |
| 5769 | try err.addMsg("undefined symbol: {s}", .{target_sym.gmi.name(coff).toSlice(coff)}); |
| 5770 | |
| 5771 | // TODO: If lib_name is set, show the user |
| 5747 | 5772 | |
| 5748 | 5773 | var prev_loc_si: Symbol.Index = .null; |
| 5749 | 5774 | for (undef_indices.items[start_i .. i + 1]) |reference_i| { |
| ... | ... | @@ -5774,9 +5799,9 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5774 | 5799 | if (section.comdat_si != .null) { |
| 5775 | 5800 | const comdat_sym = section.comdat_si.get(coff); |
| 5776 | 5801 | const comdat_name = if (comdat_sym.gmi != .none) |
| 5777 | | comdat_sym.gmi.globalName(coff).name.toSlice(coff) |
| 5802 | comdat_sym.gmi.name(coff).toSlice(coff) |
| 5778 | 5803 | else |
| 5779 | | coff.input_symbols.items[@intFromEnum(comdat_sym.extra.isli)].name.toSlice(coff); |
| 5804 | comdat_sym.extra.isli.name(coff).toSlice(coff); |
| 5780 | 5805 | |
| 5781 | 5806 | err.addNote("referenced by input COMDAT section '{s}={s}' '{f}{f}'", .{ |
| 5782 | 5807 | section_name, |
| ... | ... | @@ -5793,14 +5818,14 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5793 | 5818 | } |
| 5794 | 5819 | } else { |
| 5795 | 5820 | err.addNote("referenced by input symbol '{s}' from '{f}{f}'", .{ |
| 5796 | | loc_sym.gmi.globalName(coff).name.toSlice(coff), |
| 5821 | loc_sym.gmi.name(coff).toSlice(coff), |
| 5797 | 5822 | other_ioi.path(coff).fmtEscapeString(), |
| 5798 | 5823 | fmtMemberNameString(other_ioi.memberName(coff)), |
| 5799 | 5824 | }); |
| 5800 | 5825 | } |
| 5801 | 5826 | }, |
| 5802 | 5827 | .import_thunk => |gmi| err.addNote("referenced by import thunk for '{s}'", .{ |
| 5803 | | gmi.globalName(coff).name.toSlice(coff), |
| 5828 | gmi.name(coff).toSlice(coff), |
| 5804 | 5829 | }), |
| 5805 | 5830 | inline .nav, |
| 5806 | 5831 | .uav, |
| ... | ... | @@ -5959,7 +5984,7 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 5959 | 5984 | if (coff.exports_complete and coff.global_pending_index < coff.globals.count()) { |
| 5960 | 5985 | const gmi: Node.GlobalMapIndex = .wrap(coff.global_pending_index); |
| 5961 | 5986 | const sub_prog_node = coff.synth_prog_node.start( |
| 5962 | | gmi.globalName(coff).name.toSlice(coff), |
| 5987 | gmi.name(coff).toSlice(coff), |
| 5963 | 5988 | 0, |
| 5964 | 5989 | ); |
| 5965 | 5990 | defer sub_prog_node.end(); |
| ... | ... | @@ -6138,7 +6163,7 @@ fn idleProgNode( |
| 6138 | 6163 | coff.getNode(isi.symbol(coff).node(coff).parent(&coff.mf)).object_section.name(coff).toSlice(coff), |
| 6139 | 6164 | }) catch &name; |
| 6140 | 6165 | }, |
| 6141 | | .import_thunk => |gmi| gmi.globalName(coff).name.toSlice(coff), |
| 6166 | .import_thunk => |gmi| gmi.name(coff).toSlice(coff), |
| 6142 | 6167 | .nav => |nmi| { |
| 6143 | 6168 | const ip = &coff.base.comp.zcu.?.intern_pool; |
| 6144 | 6169 | break :name ip.getNav(nmi.navIndex(coff)).fqn.toSlice(ip); |
| ... | ... | @@ -6216,7 +6241,6 @@ fn flushUav( |
| 6216 | 6241 | } |
| 6217 | 6242 | |
| 6218 | 6243 | fn aliasGlobal(coff: *Coff, gmi: Node.GlobalMapIndex, alias_si: Symbol.Index) !void { |
| 6219 | | const gn = gmi.globalName(coff); |
| 6220 | 6244 | const si = gmi.symbol(coff); |
| 6221 | 6245 | const sym = si.get(coff); |
| 6222 | 6246 | const alias_sym = alias_si.get(coff); |
| ... | ... | @@ -6224,11 +6248,11 @@ fn aliasGlobal(coff: *Coff, gmi: Node.GlobalMapIndex, alias_si: Symbol.Index) !v |
| 6224 | 6248 | assert(sym.loc_relocs == .none); |
| 6225 | 6249 | |
| 6226 | 6250 | log.debug("aliasGlobal({s}, {?s}) {d}->{d} ({?s})", .{ |
| 6227 | | gn.name.toSlice(coff), |
| 6228 | | gn.lib_name.toSlice(coff), |
| 6251 | gmi.name(coff).toSlice(coff), |
| 6252 | gmi.libName(coff).toSlice(coff), |
| 6229 | 6253 | si, |
| 6230 | 6254 | alias_si, |
| 6231 | | if (alias_sym.gmi != .none) alias_sym.gmi.globalName(coff).name.toSlice(coff) else null, |
| 6255 | if (alias_sym.gmi != .none) alias_sym.gmi.name(coff).toSlice(coff) else null, |
| 6232 | 6256 | }); |
| 6233 | 6257 | |
| 6234 | 6258 | var ri = sym.target_relocs; |
| ... | ... | @@ -6250,7 +6274,7 @@ fn aliasGlobal(coff: *Coff, gmi: Node.GlobalMapIndex, alias_si: Symbol.Index) !v |
| 6250 | 6274 | alias_sym.target_relocs = sym.target_relocs; |
| 6251 | 6275 | sym.target_relocs = .none; |
| 6252 | 6276 | sym.gmi = alias_sym.gmi; |
| 6253 | | coff.globals.values()[gmi.unwrap().?] = alias_si; |
| 6277 | coff.globals.values()[gmi.unwrap().?].si = alias_si; |
| 6254 | 6278 | // Only apply the new relocs |
| 6255 | 6279 | try alias_si.applyTargetRelocs(coff, prev_target_relocs); |
| 6256 | 6280 | } |
| ... | ... | @@ -6258,12 +6282,18 @@ fn aliasGlobal(coff: *Coff, gmi: Node.GlobalMapIndex, alias_si: Symbol.Index) !v |
| 6258 | 6282 | fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6259 | 6283 | const comp = coff.base.comp; |
| 6260 | 6284 | const gpa = comp.gpa; |
| 6261 | | const gn = gmi.globalName(coff); |
| 6285 | const name = gmi.name(coff); |
| 6262 | 6286 | const si = gmi.symbol(coff); |
| 6263 | 6287 | |
| 6264 | 6288 | log.debug( |
| 6265 | 6289 | "flushGlobal({s}, {?s}) = n{d} {d}@{d}", |
| 6266 | | .{ gn.name.toSlice(coff), gn.lib_name.toSlice(coff), si.get(coff).ni, si, si.get(coff).section_number }, |
| 6290 | .{ |
| 6291 | name.toSlice(coff), |
| 6292 | gmi.libName(coff).toSlice(coff), |
| 6293 | si.get(coff).ni, |
| 6294 | si, |
| 6295 | si.get(coff).section_number, |
| 6296 | }, |
| 6267 | 6297 | ); |
| 6268 | 6298 | |
| 6269 | 6299 | if (!coff.isImage()) { |
| ... | ... | @@ -6271,7 +6301,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6271 | 6301 | if (coff.isArchive() and si.get(coff).ni != .none) |
| 6272 | 6302 | try coff.ensureMemberSymbol( |
| 6273 | 6303 | coff.getNode(Node.known.zcu_member).archive_member, |
| 6274 | | gn.name, |
| 6304 | name, |
| 6275 | 6305 | ); |
| 6276 | 6306 | |
| 6277 | 6307 | return true; |
| ... | ... | @@ -6292,18 +6322,18 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6292 | 6322 | |
| 6293 | 6323 | const import: Import = import: { |
| 6294 | 6324 | const sym = si.get(coff); |
| 6295 | | const global_name = gn.name.toSlice(coff); |
| 6296 | | const imp_match = std.mem.startsWith(u8, global_name, imp_prefix); |
| 6325 | const name_slice = name.toSlice(coff); |
| 6326 | const imp_match = std.mem.startsWith(u8, name_slice, imp_prefix); |
| 6297 | 6327 | |
| 6298 | 6328 | // Globals may have the __imp_ prefix already if they are undef externals from another input. |
| 6299 | 6329 | assert(sym.flags.dll_storage_class != .dllexport); |
| 6300 | 6330 | const search_name, const is_imp = if (imp_match or sym.flags.dll_storage_class != .dllimport) |
| 6301 | | .{ gn.name, imp_match } |
| 6331 | .{ name, imp_match } |
| 6302 | 6332 | else name: { |
| 6303 | | try coff.ensureUnusedStringCapacity(imp_prefix.len + global_name.len); |
| 6304 | | const name = try std.fmt.allocPrint(gpa, imp_prefix ++ "{s}", .{global_name}); |
| 6305 | | defer gpa.free(name); |
| 6306 | | break :name .{ coff.getOrPutStringAssumeCapacity(name), true }; |
| 6333 | try coff.ensureUnusedStringCapacity(imp_prefix.len + name_slice.len); |
| 6334 | const imp_name = try std.fmt.allocPrint(gpa, imp_prefix ++ "{s}", .{name_slice}); |
| 6335 | defer gpa.free(imp_name); |
| 6336 | break :name .{ coff.getOrPutStringAssumeCapacity(imp_name), true }; |
| 6307 | 6337 | }; |
| 6308 | 6338 | |
| 6309 | 6339 | const opt_alt_search_name = coff.alternate_names.get(search_name); |
| ... | ... | @@ -6317,7 +6347,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6317 | 6347 | .anti_dependency => return comp.link_diags.fail( |
| 6318 | 6348 | // TODO: Figure out what the purpose of this is |
| 6319 | 6349 | "TODO support anti_dependency weak external: {s}", |
| 6320 | | .{gn.name.toSlice(coff)}, |
| 6350 | .{name.toSlice(coff)}, |
| 6321 | 6351 | ), |
| 6322 | 6352 | }, |
| 6323 | 6353 | else => true, |
| ... | ... | @@ -6336,7 +6366,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6336 | 6366 | const member = &coff.input_archive_members.items[@intFromEnum(archive_sym.iami)]; |
| 6337 | 6367 | member: switch (member.content) { |
| 6338 | 6368 | .object => if (!member.flags.is_loaded) { |
| 6339 | | if (gn.lib_name.unwrap()) |lib_name| |
| 6369 | if (gmi.libName(coff).unwrap()) |lib_name| |
| 6340 | 6370 | if (!std.ascii.eqlIgnoreCase( |
| 6341 | 6371 | lib_name.toSlice(coff), |
| 6342 | 6372 | member.iai.path(coff).stem(), |
| ... | ... | @@ -6349,32 +6379,32 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6349 | 6379 | return false; |
| 6350 | 6380 | }, |
| 6351 | 6381 | .import => |import| { |
| 6352 | | if (gn.lib_name.unwrap()) |lib_name| |
| 6382 | if (gmi.libName(coff).unwrap()) |lib_name| |
| 6353 | 6383 | if (!std.ascii.eqlIgnoreCase( |
| 6354 | 6384 | import.lib_name.toSlice(coff), |
| 6355 | 6385 | lib_name.toSlice(coff), |
| 6356 | 6386 | )) break :member; |
| 6357 | 6387 | |
| 6358 | | const name: String.Optional = name: switch (import.name_type) { |
| 6388 | const imp_name: String.Optional = name: switch (import.name_type) { |
| 6359 | 6389 | .NAME, |
| 6360 | 6390 | .NAME_NOPREFIX, |
| 6361 | 6391 | .NAME_UNDECORATE, |
| 6362 | 6392 | => |tag| { |
| 6363 | 6393 | const symbol_name: []const u8 = import.symbol_name.toSlice(coff); |
| 6364 | | const end_match = std.mem.endsWith(u8, global_name, symbol_name); |
| 6365 | | const len_delta = global_name.len -% symbol_name.len; |
| 6394 | const end_match = std.mem.endsWith(u8, name_slice, symbol_name); |
| 6395 | const len_delta = name_slice.len -% symbol_name.len; |
| 6366 | 6396 | if (!end_match or |
| 6367 | 6397 | (!imp_match and len_delta != 0) or |
| 6368 | 6398 | (imp_match and len_delta != imp_prefix.len)) |
| 6369 | 6399 | return comp.link_diags.fail( |
| 6370 | 6400 | "global '{s}' has mismatched symbol name in import header: '{s}'", |
| 6371 | 6401 | .{ |
| 6372 | | gn.name.toSlice(coff), |
| 6402 | name.toSlice(coff), |
| 6373 | 6403 | import.symbol_name.toSlice(coff), |
| 6374 | 6404 | }, |
| 6375 | 6405 | ); |
| 6376 | 6406 | |
| 6377 | | const name = if (tag == .NAME) import.symbol_name else undecorated: { |
| 6407 | const imp_name = if (tag == .NAME) import.symbol_name else undecorated: { |
| 6378 | 6408 | var imp_name = std.mem.trimStart(u8, symbol_name, "?@_"); |
| 6379 | 6409 | if (tag == .NAME_UNDECORATE) |
| 6380 | 6410 | imp_name = std.mem.sliceTo(imp_name, '@'); |
| ... | ... | @@ -6383,7 +6413,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6383 | 6413 | break :undecorated coff.getOrPutStringAssumeCapacity(imp_name); |
| 6384 | 6414 | }; |
| 6385 | 6415 | |
| 6386 | | break :name name.toOptional(); |
| 6416 | break :name imp_name.toOptional(); |
| 6387 | 6417 | }, |
| 6388 | 6418 | .ORDINAL => break :name .none, |
| 6389 | 6419 | else => |t| return comp.link_diags.fail("TODO handle name_type {t}", .{t}), |
| ... | ... | @@ -6391,7 +6421,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6391 | 6421 | |
| 6392 | 6422 | break :import .{ |
| 6393 | 6423 | .lib_name = import.lib_name, |
| 6394 | | .name = name, |
| 6424 | .name = imp_name, |
| 6395 | 6425 | .ordinal_hint = import.import_ordinal_hint, |
| 6396 | 6426 | .kind = if (import.type == .CODE and !is_imp) .thunk else .iat_ptr, |
| 6397 | 6427 | }; |
| ... | ... | @@ -6414,7 +6444,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6414 | 6444 | const alias_gop = try coff.getOrPutGlobalSymbol(.{ |
| 6415 | 6445 | .name = sym.value.weak_alias_name.toSlice(coff), |
| 6416 | 6446 | }); |
| 6417 | | try coff.aliasGlobal(gmi, alias_gop.value_ptr.*); |
| 6447 | try coff.aliasGlobal(gmi, alias_gop.value_ptr.si); |
| 6418 | 6448 | return true; |
| 6419 | 6449 | }, |
| 6420 | 6450 | else => {}, |
| ... | ... | @@ -6422,8 +6452,8 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6422 | 6452 | |
| 6423 | 6453 | // If there was an object that had the alternate name, we've attempted to load it |
| 6424 | 6454 | if (opt_alt_search_name) |alt_search_name| { |
| 6425 | | if (coff.globals.get(.{ .name = alt_search_name, .lib_name = .none })) |alias_si| { |
| 6426 | | try coff.aliasGlobal(gmi, alias_si); |
| 6455 | if (coff.globals.get(alt_search_name)) |alias_global| { |
| 6456 | try coff.aliasGlobal(gmi, alias_global.si); |
| 6427 | 6457 | return true; |
| 6428 | 6458 | } |
| 6429 | 6459 | } |
| ... | ... | @@ -6432,9 +6462,9 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6432 | 6462 | // This is necessary for certain ntdll symbols, such as LdrRegisterDllNotification, |
| 6433 | 6463 | // which are not in the implib. |
| 6434 | 6464 | if (sym.flags.type != .unknown) { |
| 6435 | | if (gn.lib_name.unwrap()) |lib_name| break :import .{ |
| 6465 | if (gmi.libName(coff).unwrap()) |lib_name| break :import .{ |
| 6436 | 6466 | .lib_name = lib_name, |
| 6437 | | .name = gn.name.toOptional(), |
| 6467 | .name = name.toOptional(), |
| 6438 | 6468 | .ordinal_hint = 0, |
| 6439 | 6469 | .kind = if (sym.flags.type == .code) .thunk else .iat_ptr, |
| 6440 | 6470 | }; |
| ... | ... | @@ -6525,7 +6555,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6525 | 6555 | |
| 6526 | 6556 | log.debug( |
| 6527 | 6557 | "flushGlobalImport({s}, {?s}, {d}, {s})", |
| 6528 | | .{ gn.name.toSlice(coff), import.name.toSlice(coff), import.ordinal_hint, lib_name }, |
| 6558 | .{ name.toSlice(coff), import.name.toSlice(coff), import.ordinal_hint, lib_name }, |
| 6529 | 6559 | ); |
| 6530 | 6560 | |
| 6531 | 6561 | const iat_symbol_gop = try coff.import_table.iat_symbol_indices.getOrPut(gpa, .{ |
| ... | ... | @@ -6544,11 +6574,11 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6544 | 6574 | const import_address_table_ni = gop.value_ptr.import_address_table_si.node(coff); |
| 6545 | 6575 | try import_address_table_ni.resize(&coff.mf, gpa, new_symbol_table_size); |
| 6546 | 6576 | |
| 6547 | | const opt_name = import.name.toSlice(coff); |
| 6548 | | const opt_import_hint_name_index = if (opt_name) |name| blk: { |
| 6577 | const opt_imp_name = import.name.toSlice(coff); |
| 6578 | const opt_import_hint_name_index = if (opt_imp_name) |imp_name| blk: { |
| 6549 | 6579 | const import_hint_name_index = gop.value_ptr.hint_name_len; |
| 6550 | 6580 | gop.value_ptr.hint_name_len = @intCast( |
| 6551 | | import_hint_name_align.forward(import_hint_name_index + 2 + name.len + 1), |
| 6581 | import_hint_name_align.forward(import_hint_name_index + 2 + imp_name.len + 1), |
| 6552 | 6582 | ); |
| 6553 | 6583 | try gop.value_ptr.import_hint_name_table_ni.resize(&coff.mf, gpa, gop.value_ptr.hint_name_len); |
| 6554 | 6584 | break :blk import_hint_name_index; |
| ... | ... | @@ -6558,8 +6588,8 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6558 | 6588 | const import_hint_name_slice = gop.value_ptr.import_hint_name_table_ni.slice(&coff.mf); |
| 6559 | 6589 | const ordinal_hint: *u16 = @ptrCast(@alignCast(import_hint_name_slice[import_hint_name_index..][0..2])); |
| 6560 | 6590 | ordinal_hint.* = std.mem.nativeTo(u16, import.ordinal_hint, target_endian); |
| 6561 | | @memcpy(import_hint_name_slice[import_hint_name_index + 2 ..][0..opt_name.?.len], opt_name.?); |
| 6562 | | @memset(import_hint_name_slice[import_hint_name_index + 2 + opt_name.?.len ..], 0); |
| 6591 | @memcpy(import_hint_name_slice[import_hint_name_index + 2 ..][0..opt_imp_name.?.len], opt_imp_name.?); |
| 6592 | @memset(import_hint_name_slice[import_hint_name_index + 2 + opt_imp_name.?.len ..], 0); |
| 6563 | 6593 | break :blk coff.computeNodeRva(gop.value_ptr.import_hint_name_table_ni) + import_hint_name_index; |
| 6564 | 6594 | } else 0; |
| 6565 | 6595 | |
| ... | ... | @@ -6687,7 +6717,7 @@ fn flushSpecialSymbol(coff: *Coff, pending: SpecialSymbol) !SpecialSymbol { |
| 6687 | 6717 | if (entry_si != .null) { |
| 6688 | 6718 | log.debug( |
| 6689 | 6719 | "entry({s}, {d})", |
| 6690 | | .{ entry_si.get(coff).gmi.globalName(coff).name.toSlice(coff), entry_si }, |
| 6720 | .{ entry_si.get(coff).gmi.name(coff).toSlice(coff), entry_si }, |
| 6691 | 6721 | ); |
| 6692 | 6722 | |
| 6693 | 6723 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| ... | ... | @@ -7379,10 +7409,7 @@ fn updateExportsInner( |
| 7379 | 7409 | const name = @"export".opts.name.toSlice(ip); |
| 7380 | 7410 | |
| 7381 | 7411 | // TODO: add an errMsg if this conflicts with an existing symbol |
| 7382 | | const export_si = try coff.globalSymbol(.{ |
| 7383 | | .name = name, |
| 7384 | | .lib_name = null, |
| 7385 | | }); |
| 7412 | const export_si = try coff.globalSymbol(.{ .name = name }); |
| 7386 | 7413 | const export_sym = export_si.get(coff); |
| 7387 | 7414 | export_sym.ni = exported_ni; |
| 7388 | 7415 | export_sym.rva = exported_sym.rva; |
| ... | ... | @@ -7605,6 +7632,8 @@ fn printSymbol( |
| 7605 | 7632 | } else { |
| 7606 | 7633 | try w.writeAll("| "); |
| 7607 | 7634 | try coff.printNodeName(w, tid, node); |
| 7635 | if (sym.flags.extra_tag == .isli) |
| 7636 | try w.print(" | {s}", .{sym.extra.isli.name(coff).toSlice(coff)}); |
| 7608 | 7637 | try w.writeByte('\n'); |
| 7609 | 7638 | } |
| 7610 | 7639 | } |
| ... | ... | @@ -7617,9 +7646,8 @@ fn fmtGlobalName(coff: *Coff, gmi: Node.GlobalMapIndex) std.fmt.Alt(FmtGlobalNam |
| 7617 | 7646 | |
| 7618 | 7647 | fn globalNameEscape(data: FmtGlobalName, w: *std.Io.Writer) std.Io.Writer.Error!void { |
| 7619 | 7648 | if (data.gmi == .none) return; |
| 7620 | | const gn = data.gmi.globalName(data.coff); |
| 7621 | | try w.writeAll(gn.name.toSlice(data.coff)); |
| 7622 | | if (gn.lib_name.unwrap()) |lib_name| |
| 7649 | try w.writeAll(data.gmi.name(data.coff).toSlice(data.coff)); |
| 7650 | if (data.gmi.libName(data.coff).unwrap()) |lib_name| |
| 7623 | 7651 | try w.print("({s})", .{lib_name.toSlice(data.coff)}); |
| 7624 | 7652 | } |
| 7625 | 7653 | |
| ... | ... | @@ -7645,7 +7673,7 @@ fn printNodeName( |
| 7645 | 7673 | if (is.comdat_si != .null) { |
| 7646 | 7674 | const comdat_sym = is.comdat_si.get(coff); |
| 7647 | 7675 | const comdat_name = if (comdat_sym.gmi != .none) |
| 7648 | | comdat_sym.gmi.globalName(coff).name.toSlice(coff) |
| 7676 | comdat_sym.gmi.name(coff).toSlice(coff) |
| 7649 | 7677 | else |
| 7650 | 7678 | coff.input_symbols.items[@intFromEnum(comdat_sym.extra.isli)].name.toSlice(coff); |
| 7651 | 7679 | |
| ... | ... | @@ -7664,10 +7692,9 @@ fn printNodeName( |
| 7664 | 7692 | }), |
| 7665 | 7693 | .import_thunk, |
| 7666 | 7694 | => |gmi| { |
| 7667 | | const gn = gmi.globalName(coff); |
| 7668 | 7695 | try w.writeByte('('); |
| 7669 | | if (gn.lib_name.toSlice(coff)) |lib_name| try w.print("{s}.dll, ", .{lib_name}); |
| 7670 | | try w.print("{s})", .{gn.name.toSlice(coff)}); |
| 7696 | if (gmi.libName(coff).toSlice(coff)) |lib_name| try w.print("{s}.dll, ", .{lib_name}); |
| 7697 | try w.print("{s})", .{gmi.name(coff).toSlice(coff)}); |
| 7671 | 7698 | }, |
| 7672 | 7699 | .nav => |nmi| { |
| 7673 | 7700 | const zcu = coff.base.comp.zcu.?; |
| ... | ... | @@ -7695,10 +7722,9 @@ fn printNodeName( |
| 7695 | 7722 | .builtin => |si| { |
| 7696 | 7723 | const sym = si.get(coff); |
| 7697 | 7724 | if (sym.gmi != .none) { |
| 7698 | | const gn = sym.gmi.globalName(coff); |
| 7699 | 7725 | try w.writeByte('('); |
| 7700 | | if (gn.lib_name.toSlice(coff)) |lib_name| try w.print("{s}.dll, ", .{lib_name}); |
| 7701 | | try w.print("{s})", .{gn.name.toSlice(coff)}); |
| 7726 | if (sym.gmi.libName(coff).toSlice(coff)) |lib_name| try w.print("{s}.dll, ", .{lib_name}); |
| 7727 | try w.print("{s})", .{sym.gmi.name(coff).toSlice(coff)}); |
| 7702 | 7728 | } |
| 7703 | 7729 | }, |
| 7704 | 7730 | } |