diff --git a/src/Compilation.zig b/src/Compilation.zig index 7b7e85d0f7..c742e59af5 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -956,7 +956,6 @@ pub const InitOptions = struct { emit_docs: ?EmitLoc = null, /// `null` means to not emit an import lib. emit_implib: ?EmitLoc = null, - dll_export_fns: ?bool = false, /// Normally when using LLD to link, Zig uses a file named "lld.id" in the /// same directory as the output binary which contains the hash of the link /// operation, allowing Zig to skip linking when the hash would be unchanged. @@ -989,7 +988,6 @@ pub const InitOptions = struct { want_compiler_rt: ?bool = null, want_lto: ?bool = null, formatted_panics: ?bool = null, - rdynamic: bool = false, function_sections: bool = false, data_sections: bool = false, no_builtin: bool = false, @@ -1200,8 +1198,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { const link_libc = options.config.link_libc; - const dll_export_fns = options.dll_export_fns orelse (is_dyn_lib or options.rdynamic); - const libc_dirs = try detectLibCIncludeDirs( arena, options.zig_lib_directory.path.?, @@ -1524,10 +1520,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .gc_sections = options.linker_gc_sections, .eh_frame_hdr = link_eh_frame_hdr, .emit_relocs = options.link_emit_relocs, - .rdynamic = options.rdynamic, .soname = options.soname, .compatibility_version = options.compatibility_version, - .dll_export_fns = dll_export_fns, .each_lib_rpath = each_lib_rpath, .build_id = build_id, .disable_lld_caching = options.disable_lld_caching or cache_mode == .whole, @@ -1555,7 +1549,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { // Synchronize with other matching comments: ZigOnlyHashStuff hash.add(use_llvm); hash.add(options.config.use_lib_llvm); - hash.add(dll_export_fns); + hash.add(options.config.dll_export_fns); hash.add(options.config.is_test); hash.add(options.config.test_evented_io); hash.addOptionalBytes(options.test_filter); @@ -2430,6 +2424,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes man.hash.add(comp.config.import_memory); man.hash.add(comp.config.export_memory); man.hash.add(comp.config.shared_memory); + man.hash.add(comp.config.dll_export_fns); + man.hash.add(comp.config.rdynamic); if (comp.bin_file) |lf| { man.hash.add(lf.stack_size); @@ -2442,7 +2438,6 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes switch (lf.tag) { .elf => { const elf = lf.cast(link.File.Elf).?; - man.hash.add(elf.rdynamic); man.hash.add(elf.eh_frame_hdr); man.hash.add(elf.image_base); man.hash.add(elf.emit_relocs); @@ -2468,7 +2463,6 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes }, .wasm => { const wasm = lf.cast(link.File.Wasm).?; - man.hash.add(wasm.rdynamic); man.hash.addOptional(wasm.initial_memory); man.hash.addOptional(wasm.max_memory); man.hash.addOptional(wasm.global_base); @@ -2485,7 +2479,6 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes }, .coff => { const coff = lf.cast(link.File.Coff).?; - man.hash.add(coff.dll_export_fns); man.hash.add(coff.image_base); man.hash.addOptional(coff.subsystem); man.hash.add(coff.tsaware); diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index 44ace55ae4..442b7a1b9a 100644 --- a/src/Compilation/Config.zig +++ b/src/Compilation/Config.zig @@ -41,6 +41,8 @@ entry: ?[]const u8, debug_format: DebugFormat, root_strip: bool, root_error_tracing: bool, +dll_export_fns: bool, +rdynamic: bool, pub const CFrontend = enum { clang, aro }; @@ -93,6 +95,8 @@ pub const Options = struct { shared_memory: ?bool = null, test_evented_io: bool = false, debug_format: ?Config.DebugFormat = null, + dll_export_fns: ?bool = null, + rdynamic: ?bool = null, }; pub fn resolve(options: Options) !Config { @@ -415,6 +419,17 @@ pub fn resolve(options: Options) !Config { const any_error_tracing = root_error_tracing or options.any_error_tracing; + const rdynamic = options.rdynamic orelse false; + + const dll_export_fns = b: { + if (options.dll_export_fns) |x| break :b x; + if (rdynamic) break :b true; + break :b switch (options.output_mode) { + .Obj, .Exe => false, + .Lib => link_mode == .Dynamic, + }; + }; + return .{ .output_mode = options.output_mode, .have_zcu = options.have_zcu, @@ -443,6 +458,8 @@ pub fn resolve(options: Options) !Config { .wasi_exec_model = wasi_exec_model, .debug_format = debug_format, .root_strip = root_strip, + .dll_export_fns = dll_export_fns, + .rdynamic = rdynamic, }; } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 42180c6529..7e25a4b59b 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1672,6 +1672,7 @@ pub const Object = struct { // because we call `updateExports` at the end of `updateFunc` and `updateDecl`. const global_index = self.decl_map.get(decl_index) orelse return; const decl = mod.declPtr(decl_index); + const comp = mod.comp; if (decl.isExtern(mod)) { const decl_name = decl_name: { const decl_name = mod.intern_pool.stringToSlice(decl.name); @@ -1696,7 +1697,8 @@ pub const Object = struct { try global_index.rename(decl_name, &self.builder); global_index.setLinkage(.external, &self.builder); global_index.setUnnamedAddr(.default, &self.builder); - if (wantDllExports(mod)) global_index.setDllStorageClass(.default, &self.builder); + if (comp.config.dll_export_fns) + global_index.setDllStorageClass(.default, &self.builder); if (self.di_map.get(decl)) |di_node| { const decl_name_slice = decl_name.slice(&self.builder).?; if (try decl.isFunction(mod)) { @@ -1762,7 +1764,8 @@ pub const Object = struct { ); try global_index.rename(fqn, &self.builder); global_index.setLinkage(.internal, &self.builder); - if (wantDllExports(mod)) global_index.setDllStorageClass(.default, &self.builder); + if (comp.config.dll_export_fns) + global_index.setDllStorageClass(.default, &self.builder); global_index.setUnnamedAddr(.unnamed_addr, &self.builder); if (decl.val.getVariable(mod)) |decl_var| { const decl_namespace = mod.namespacePtr(decl.src_namespace); @@ -1821,7 +1824,9 @@ pub const Object = struct { exports: []const *Module.Export, ) link.File.UpdateExportsError!void { global_index.setUnnamedAddr(.default, &o.builder); - if (wantDllExports(mod)) global_index.setDllStorageClass(.dllexport, &o.builder); + const comp = mod.comp; + if (comp.config.dll_export_fns) + global_index.setDllStorageClass(.dllexport, &o.builder); global_index.setLinkage(switch (exports[0].opts.linkage) { .Internal => unreachable, .Strong => .external, @@ -11758,9 +11763,3 @@ fn constraintAllowsRegister(constraint: []const u8) bool { } } else return false; } - -fn wantDllExports(zcu: *const Zcu) bool { - const lf = zcu.bin_file.?; - const coff = lf.cast(link.File.Coff) orelse return false; - return coff.dll_export_fns; -} diff --git a/src/link.zig b/src/link.zig index 77169afa29..14b180ed2a 100644 --- a/src/link.zig +++ b/src/link.zig @@ -88,7 +88,6 @@ pub const File = struct { image_base: ?u64, eh_frame_hdr: bool, emit_relocs: bool, - rdynamic: bool, z_nodelete: bool, z_notext: bool, z_defs: bool, @@ -110,7 +109,6 @@ pub const File = struct { max_memory: ?u64, export_symbol_names: []const []const u8, global_base: ?u64, - dll_export_fns: bool, each_lib_rpath: bool, build_id: std.zig.BuildId, disable_lld_caching: bool, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 52ca7e554c..c02aecf2db 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -8,7 +8,6 @@ llvm_object: ?*LlvmObject = null, base: link.File, image_base: u64, -dll_export_fns: bool, subsystem: ?std.Target.SubSystem, tsaware: bool, nxcompat: bool, @@ -416,7 +415,6 @@ pub fn createEmpty( .Obj => 0, }, - .dll_export_fns = options.dll_export_fns, .subsystem = options.subsystem, .tsaware = options.tsaware, .nxcompat = options.nxcompat, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index fe89a6321f..47b4712b57 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1,6 +1,5 @@ base: link.File, image_base: u64, -rdynamic: bool, eh_frame_hdr: bool, emit_relocs: bool, z_nodelete: bool, @@ -370,7 +369,7 @@ pub fn createEmpty( else => 0x1000, }; const is_dyn_lib = output_mode == .Lib and link_mode == .Dynamic; - const default_sym_version: elf.Elf64_Versym = if (is_dyn_lib or options.rdynamic) + const default_sym_version: elf.Elf64_Versym = if (is_dyn_lib or comp.config.rdynamic) elf.VER_NDX_GLOBAL else elf.VER_NDX_LOCAL; @@ -402,7 +401,6 @@ pub fn createEmpty( }; }, - .rdynamic = options.rdynamic, .eh_frame_hdr = options.eh_frame_hdr, .emit_relocs = options.emit_relocs, .z_nodelete = options.z_nodelete, @@ -1725,7 +1723,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { try argv.append("--eh-frame-hdr"); } - if (self.rdynamic) { + if (comp.config.rdynamic) { try argv.append("--export-dynamic"); } @@ -2434,7 +2432,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v man.hash.addOptional(self.sort_section); man.hash.add(self.eh_frame_hdr); man.hash.add(self.emit_relocs); - man.hash.add(self.rdynamic); + man.hash.add(comp.config.rdynamic); man.hash.addListOfBytes(self.lib_dirs); man.hash.addListOfBytes(self.base.rpath_list); man.hash.add(self.each_lib_rpath); @@ -2637,7 +2635,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v try argv.append("--emit-relocs"); } - if (self.rdynamic) { + if (comp.config.rdynamic) { try argv.append("--export-dynamic"); } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 6488231afa..874cc2d9b3 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -39,7 +39,6 @@ pub const base_tag: link.File.Tag = .wasm; base: link.File, import_symbols: bool, export_symbol_names: []const []const u8, -rdynamic: bool, global_base: ?u64, initial_memory: ?u64, max_memory: ?u64, @@ -563,7 +562,6 @@ pub fn createEmpty( .export_table = options.export_table, .import_symbols = options.import_symbols, .export_symbol_names = options.export_symbol_names, - .rdynamic = options.rdynamic, .global_base = options.global_base, .initial_memory = options.initial_memory, .max_memory = options.max_memory, @@ -2973,8 +2971,9 @@ fn mergeTypes(wasm: *Wasm) !void { } fn setupExports(wasm: *Wasm) !void { - const gpa = wasm.base.comp.gpa; - if (wasm.base.comp.config.output_mode == .Obj) return; + const comp = wasm.base.comp; + const gpa = comp.gpa; + if (comp.config.output_mode == .Obj) return; log.debug("Building exports from symbols", .{}); const force_exp_names = wasm.export_symbol_names; @@ -2999,7 +2998,7 @@ fn setupExports(wasm: *Wasm) !void { for (wasm.resolved_symbols.keys()) |sym_loc| { const symbol = sym_loc.getSymbol(wasm); - if (!symbol.isExported(wasm.rdynamic)) continue; + if (!symbol.isExported(comp.config.rdynamic)) continue; const sym_name = sym_loc.getName(wasm); const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: { @@ -4789,7 +4788,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! try argv.append(arg); } - if (wasm.rdynamic) { + if (comp.config.rdynamic) { try argv.append("--export-dynamic"); } @@ -5288,7 +5287,7 @@ fn markReferences(wasm: *Wasm) !void { for (wasm.resolved_symbols.keys()) |sym_loc| { const sym = sym_loc.getSymbol(wasm); - if (sym.isExported(wasm.rdynamic) or sym.isNoStrip() or !do_garbage_collect) { + if (sym.isExported(comp.config.rdynamic) or sym.isNoStrip() or !do_garbage_collect) { try wasm.mark(sym_loc); continue; } diff --git a/src/main.zig b/src/main.zig index b73023e5b3..ee6468d41f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -786,7 +786,6 @@ fn buildOutputType( arg_mode: ArgMode, ) !void { var provided_name: ?[]const u8 = null; - var dll_export_fns: ?bool = null; var root_src_file: ?[]const u8 = null; var version: std.SemanticVersion = .{ .major = 0, .minor = 0, .patch = 0 }; var have_version = false; @@ -824,7 +823,6 @@ fn buildOutputType( var soname: SOName = undefined; var want_native_include_dirs = false; var want_compiler_rt: ?bool = null; - var rdynamic: bool = false; var linker_script: ?[]const u8 = null; var version_script: ?[]const u8 = null; var disable_c_depfile = false; @@ -1411,7 +1409,7 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "-fno-error-tracing")) { mod_opts.error_tracing = false; } else if (mem.eql(u8, arg, "-rdynamic")) { - rdynamic = true; + create_module.opts.rdynamic = true; } else if (mem.eql(u8, arg, "-fsoname")) { soname = .yes_default_value; } else if (mem.startsWith(u8, arg, "-fsoname=")) { @@ -1472,9 +1470,9 @@ fn buildOutputType( lib_preferred_mode = .Static; lib_search_strategy = .no_fallback; } else if (mem.eql(u8, arg, "-fdll-export-fns")) { - dll_export_fns = true; + create_module.opts.dll_export_fns = true; } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) { - dll_export_fns = false; + create_module.opts.dll_export_fns = false; } else if (mem.eql(u8, arg, "--show-builtin")) { show_builtin = true; emit_bin = .no; @@ -1882,7 +1880,7 @@ fn buildOutputType( create_module.opts.link_mode = .Dynamic; is_shared_lib = true; }, - .rdynamic => rdynamic = true, + .rdynamic => create_module.opts.rdynamic = true, .wl => { var split_it = mem.splitScalar(u8, it.only_arg, ','); while (split_it.next()) |linker_arg| { @@ -2136,7 +2134,7 @@ fn buildOutputType( mem.eql(u8, arg, "--export-dynamic") or mem.eql(u8, arg, "-export-dynamic")) { - rdynamic = true; + create_module.opts.rdynamic = true; } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { version_script = linker_args_it.nextOrFatal(); } else if (mem.eql(u8, arg, "-O")) { @@ -2295,7 +2293,7 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "--high-entropy-va")) { // This option does not do anything. } else if (mem.eql(u8, arg, "--export-all-symbols")) { - rdynamic = true; + create_module.opts.rdynamic = true; } else if (mem.eql(u8, arg, "--color-diagnostics") or mem.eql(u8, arg, "--color-diagnostics=always")) { @@ -3365,7 +3363,6 @@ fn buildOutputType( .emit_llvm_bc = emit_llvm_bc_resolved.data, .emit_docs = emit_docs_resolved.data, .emit_implib = emit_implib_resolved.data, - .dll_export_fns = dll_export_fns, .lib_dirs = lib_dirs.items, .rpath_list = rpath_list.items, .symbol_wrap_set = symbol_wrap_set, @@ -3381,7 +3378,6 @@ fn buildOutputType( .wasi_emulated_libs = create_module.wasi_emulated_libs.items, .want_compiler_rt = want_compiler_rt, .hash_style = hash_style, - .rdynamic = rdynamic, .linker_script = linker_script, .version_script = version_script, .disable_c_depfile = disable_c_depfile,