From 0dc210f950ff926fb8e57288a8ff257abc942b6d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 27 Mar 2023 18:23:25 +0200 Subject: [PATCH] link: pass expected lib name as hint in getGlobalSymbol() --- src/arch/aarch64/CodeGen.zig | 14 ++++---------- src/arch/wasm/CodeGen.zig | 2 +- src/arch/x86_64/CodeGen.zig | 14 ++++---------- src/link.zig | 12 +++++++----- src/link/Coff.zig | 3 ++- src/link/MachO.zig | 3 ++- src/link/Wasm.zig | 3 ++- 7 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index e2e2ce9ead..ee23696950 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -4318,16 +4318,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }); } else if (func_value.castTag(.extern_fn)) |func_payload| { const extern_fn = func_payload.data; - const decl_name = mod.declPtr(extern_fn.owner_decl).name; - if (extern_fn.lib_name) |lib_name| { - log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{ - decl_name, - lib_name, - }); - } - + const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); + const lib_name = mem.sliceTo(extern_fn.lib_name, 0); if (self.bin_file.cast(link.File.MachO)) |macho_file| { - const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; _ = try self.addInst(.{ @@ -4340,7 +4334,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }, }); } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { - const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); try self.genSetReg(Type.initTag(.u64), .x30, .{ .linker_load = .{ .type = .import, diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 9af66eb40c..199ddada65 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -6121,7 +6121,7 @@ fn callIntrinsic( args: []const WValue, ) InnerError!WValue { assert(param_types.len == args.len); - const symbol_index = func.bin_file.base.getGlobalSymbol(name) catch |err| { + const symbol_index = func.bin_file.base.getGlobalSymbol(name, null) catch |err| { return func.fail("Could not find or create global symbol '{s}'", .{@errorName(err)}); }; diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index b071d14447..5ddc9c77ca 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -5317,16 +5317,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier } else unreachable; } else if (func_value.castTag(.extern_fn)) |func_payload| { const extern_fn = func_payload.data; - const decl_name = mod.declPtr(extern_fn.owner_decl).name; - if (extern_fn.lib_name) |lib_name| { - log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{ - decl_name, - lib_name, - }); - } - + const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); + const lib_name = mem.sliceTo(extern_fn.lib_name, 0); if (self.bin_file.cast(link.File.Coff)) |coff_file| { - const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); try self.genSetReg(Type.initTag(.usize), .rax, .{ .linker_load = .{ .type = .import, @@ -5335,7 +5329,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }); try self.asmRegister(.call, .rax); } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { - const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; _ = try self.addInst(.{ diff --git a/src/link.zig b/src/link.zig index ae6c02c08b..a7c3ac51bc 100644 --- a/src/link.zig +++ b/src/link.zig @@ -504,18 +504,20 @@ pub const File = struct { /// Called from within CodeGen to retrieve the symbol index of a global symbol. /// If no symbol exists yet with this name, a new undefined global symbol will /// be created. This symbol may get resolved once all relocatables are (re-)linked. - pub fn getGlobalSymbol(base: *File, name: []const u8) UpdateDeclError!u32 { + /// Optionally, it is possible to specify where to expect the symbol defined if it + /// is an import. + pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) UpdateDeclError!u32 { if (build_options.only_c) @compileError("unreachable"); - log.debug("getGlobalSymbol '{s}'", .{name}); + log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name }); switch (base.tag) { // zig fmt: off - .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name), + .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name, lib_name), .elf => unreachable, - .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name), + .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name, lib_name), .plan9 => unreachable, .spirv => unreachable, .c => unreachable, - .wasm => return @fieldParentPtr(Wasm, "base", base).getGlobalSymbol(name), + .wasm => return @fieldParentPtr(Wasm, "base", base).getGlobalSymbol(name, lib_name), .nvptx => unreachable, // zig fmt: on } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 2374bf9517..8d2a4ad16e 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1526,7 +1526,8 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link return 0; } -pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { +pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name: ?[]const u8) !u32 { + _ = lib_name; const gop = try self.getOrPutGlobalPtr(name); const global_index = self.getGlobalIndex(name).?; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 2f594d1fda..885afd37c3 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3202,7 +3202,8 @@ fn insertSection(self: *MachO, segment_index: u8, header: macho.section_64) !u8 return insertion_index; } -pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { +pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { + _ = lib_name; const gpa = self.base.allocator; const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 3561c86ce8..e59b83176c 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1573,7 +1573,8 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In /// such as an exported or imported symbol. /// If the symbol does not yet exist, creates a new one symbol instead /// and then returns the index to it. -pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8) !u32 { +pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 { + _ = lib_name; const name_index = try wasm.string_table.put(wasm.base.allocator, name); const gop = try wasm.globals.getOrPut(wasm.base.allocator, name_index); if (gop.found_existing) {