| author | |
| committer | |
| log | 0789e91eeb08495c5084067df2b2dab410197364 |
| tree | bf5bdee3e86bf182abd95c98d6811a3f5beace99 |
| parent | 3b6cb257dfbcfe7217cdb00819615d1cf1e6b89c |
22 files changed, 511 insertions(+), 429 deletions(-)
src/Compilation.zig+50-41| ... | @@ -76,6 +76,7 @@ framework_dirs: []const []const u8, | ... | @@ -76,6 +76,7 @@ framework_dirs: []const []const u8, |
| 76 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), | 76 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| 77 | version: ?std.SemanticVersion, | 77 | version: ?std.SemanticVersion, |
| 78 | libc_installation: ?*const LibCInstallation, | 78 | libc_installation: ?*const LibCInstallation, |
| 79 | skip_linker_dependencies: bool, | ||
| 79 | 80 | ||
| 80 | c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{}, | 81 | c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{}, |
| 81 | win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) = | 82 | win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) = |
| ... | @@ -940,7 +941,7 @@ pub const InitOptions = struct { | ... | @@ -940,7 +941,7 @@ pub const InitOptions = struct { |
| 940 | /// * getpid | 941 | /// * getpid |
| 941 | /// * mman | 942 | /// * mman |
| 942 | /// * signal | 943 | /// * signal |
| 943 | wasi_emulated_libs: []const wasi_libc.CRTFile = &[0]wasi_libc.CRTFile{}, | 944 | wasi_emulated_libs: []const wasi_libc.CRTFile = &.{}, |
| 944 | /// This means that if the output mode is an executable it will be a | 945 | /// This means that if the output mode is an executable it will be a |
| 945 | /// Position Independent Executable. If the output mode is not an | 946 | /// Position Independent Executable. If the output mode is not an |
| 946 | /// executable this field is ignored. | 947 | /// executable this field is ignored. |
| ... | @@ -1238,7 +1239,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1238,7 +1239,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1238 | const sysroot = options.sysroot orelse libc_dirs.sysroot; | 1239 | const sysroot = options.sysroot orelse libc_dirs.sysroot; |
| 1239 | 1240 | ||
| 1240 | const include_compiler_rt = options.want_compiler_rt orelse | 1241 | const include_compiler_rt = options.want_compiler_rt orelse |
| 1241 | (!options.skip_linker_dependencies and is_exe_or_dyn_lib); | 1242 | (!comp.skip_linker_dependencies and is_exe_or_dyn_lib); |
| 1242 | 1243 | ||
| 1243 | if (include_compiler_rt and output_mode == .Obj) { | 1244 | if (include_compiler_rt and output_mode == .Obj) { |
| 1244 | // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");` | 1245 | // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");` |
| ... | @@ -1639,6 +1640,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1639,6 +1640,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1639 | .objects = options.link_objects, | 1640 | .objects = options.link_objects, |
| 1640 | .framework_dirs = options.framework_dirs, | 1641 | .framework_dirs = options.framework_dirs, |
| 1641 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, | 1642 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, |
| 1643 | .skip_linker_dependencies = options.skip_linker_dependencies, | ||
| 1642 | }; | 1644 | }; |
| 1643 | 1645 | ||
| 1644 | if (bin_file_emit) |emit| { | 1646 | if (bin_file_emit) |emit| { |
| ... | @@ -1695,7 +1697,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1695,7 +1697,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1695 | .soname = options.soname, | 1697 | .soname = options.soname, |
| 1696 | .compatibility_version = options.compatibility_version, | 1698 | .compatibility_version = options.compatibility_version, |
| 1697 | .dll_export_fns = dll_export_fns, | 1699 | .dll_export_fns = dll_export_fns, |
| 1698 | .skip_linker_dependencies = options.skip_linker_dependencies, | ||
| 1699 | .parent_compilation_link_libc = options.parent_compilation_link_libc, | 1700 | .parent_compilation_link_libc = options.parent_compilation_link_libc, |
| 1700 | .each_lib_rpath = each_lib_rpath, | 1701 | .each_lib_rpath = each_lib_rpath, |
| 1701 | .build_id = build_id, | 1702 | .build_id = build_id, |
| ... | @@ -1765,9 +1766,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1765,9 +1766,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1765 | } | 1766 | } |
| 1766 | } | 1767 | } |
| 1767 | 1768 | ||
| 1768 | const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_sub_path != null; | 1769 | const have_bin_emit = comp.bin_file != null or comp.whole_bin_sub_path != null; |
| 1769 | 1770 | ||
| 1770 | if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies and target.ofmt != .c) { | 1771 | if (have_bin_emit and !comp.skip_linker_dependencies and target.ofmt != .c) { |
| 1771 | if (target.isDarwin()) { | 1772 | if (target.isDarwin()) { |
| 1772 | switch (target.abi) { | 1773 | switch (target.abi) { |
| 1773 | .none, | 1774 | .none, |
| ... | @@ -1808,27 +1809,34 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1808,27 +1809,34 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1808 | .{ .musl_crt_file = .crt1_o }, | 1809 | .{ .musl_crt_file = .crt1_o }, |
| 1809 | .{ .musl_crt_file = .scrt1_o }, | 1810 | .{ .musl_crt_file = .scrt1_o }, |
| 1810 | .{ .musl_crt_file = .rcrt1_o }, | 1811 | .{ .musl_crt_file = .rcrt1_o }, |
| 1811 | switch (comp.bin_file.options.link_mode) { | 1812 | switch (comp.config.link_mode) { |
| 1812 | .Static => .{ .musl_crt_file = .libc_a }, | 1813 | .Static => .{ .musl_crt_file = .libc_a }, |
| 1813 | .Dynamic => .{ .musl_crt_file = .libc_so }, | 1814 | .Dynamic => .{ .musl_crt_file = .libc_so }, |
| 1814 | }, | 1815 | }, |
| 1815 | }); | 1816 | }); |
| 1816 | } | 1817 | } |
| 1817 | if (comp.wantBuildWasiLibcFromSource()) { | ||
| 1818 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; | ||
| 1819 | 1818 | ||
| 1820 | const wasi_emulated_libs = comp.bin_file.options.wasi_emulated_libs; | 1819 | if (comp.bin_file) |lf| { |
| 1821 | try comp.work_queue.ensureUnusedCapacity(wasi_emulated_libs.len + 2); // worst-case we need all components | 1820 | if (lf.cast(link.File.Wasm)) |wasm| { |
| 1822 | for (wasi_emulated_libs) |crt_file| { | 1821 | if (comp.wantBuildWasiLibcFromSource()) { |
| 1823 | comp.work_queue.writeItemAssumeCapacity(.{ | 1822 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1824 | .wasi_libc_crt_file = crt_file, | 1823 | |
| 1825 | }); | 1824 | // worst-case we need all components |
| 1825 | try comp.work_queue.ensureUnusedCapacity(wasm.wasi_emulated_libs.len + 2); | ||
| 1826 | |||
| 1827 | for (wasm.wasi_emulated_libs) |crt_file| { | ||
| 1828 | comp.work_queue.writeItemAssumeCapacity(.{ | ||
| 1829 | .wasi_libc_crt_file = crt_file, | ||
| 1830 | }); | ||
| 1831 | } | ||
| 1832 | comp.work_queue.writeAssumeCapacity(&[_]Job{ | ||
| 1833 | .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(options.config.wasi_exec_model) }, | ||
| 1834 | .{ .wasi_libc_crt_file = .libc_a }, | ||
| 1835 | }); | ||
| 1836 | } | ||
| 1826 | } | 1837 | } |
| 1827 | comp.work_queue.writeAssumeCapacity(&[_]Job{ | ||
| 1828 | .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(options.config.wasi_exec_model) }, | ||
| 1829 | .{ .wasi_libc_crt_file = .libc_a }, | ||
| 1830 | }); | ||
| 1831 | } | 1838 | } |
| 1839 | |||
| 1832 | if (comp.wantBuildMinGWFromSource()) { | 1840 | if (comp.wantBuildMinGWFromSource()) { |
| 1833 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; | 1841 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1834 | 1842 | ||
| ... | @@ -1863,27 +1871,29 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1863,27 +1871,29 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1863 | if (comp.wantBuildLibUnwindFromSource()) { | 1871 | if (comp.wantBuildLibUnwindFromSource()) { |
| 1864 | try comp.work_queue.writeItem(.{ .libunwind = {} }); | 1872 | try comp.work_queue.writeItem(.{ .libunwind = {} }); |
| 1865 | } | 1873 | } |
| 1866 | if (build_options.have_llvm and is_exe_or_dyn_lib and comp.bin_file.options.link_libcpp) { | 1874 | if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) { |
| 1867 | try comp.work_queue.writeItem(.libcxx); | 1875 | try comp.work_queue.writeItem(.libcxx); |
| 1868 | try comp.work_queue.writeItem(.libcxxabi); | 1876 | try comp.work_queue.writeItem(.libcxxabi); |
| 1869 | } | 1877 | } |
| 1870 | if (build_options.have_llvm and comp.bin_file.options.tsan) { | 1878 | if (build_options.have_llvm and comp.config.any_sanitize_thread) { |
| 1871 | try comp.work_queue.writeItem(.libtsan); | 1879 | try comp.work_queue.writeItem(.libtsan); |
| 1872 | } | 1880 | } |
| 1873 | 1881 | ||
| 1874 | if (comp.getTarget().isMinGW() and comp.config.any_non_single_threaded) { | 1882 | if (comp.bin_file) |lf| { |
| 1875 | // LLD might drop some symbols as unused during LTO and GCing, therefore, | 1883 | if (comp.getTarget().isMinGW() and comp.config.any_non_single_threaded) { |
| 1876 | // we force mark them for resolution here. | 1884 | // LLD might drop some symbols as unused during LTO and GCing, therefore, |
| 1885 | // we force mark them for resolution here. | ||
| 1877 | 1886 | ||
| 1878 | const tls_index_sym = switch (comp.getTarget().cpu.arch) { | 1887 | const tls_index_sym = switch (comp.getTarget().cpu.arch) { |
| 1879 | .x86 => "__tls_index", | 1888 | .x86 => "__tls_index", |
| 1880 | else => "_tls_index", | 1889 | else => "_tls_index", |
| 1881 | }; | 1890 | }; |
| 1882 | 1891 | ||
| 1883 | try comp.bin_file.options.force_undefined_symbols.put(comp.gpa, tls_index_sym, {}); | 1892 | try lf.force_undefined_symbols.put(comp.gpa, tls_index_sym, {}); |
| 1893 | } | ||
| 1884 | } | 1894 | } |
| 1885 | 1895 | ||
| 1886 | if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) { | 1896 | if (comp.include_compiler_rt and capable_of_building_compiler_rt) { |
| 1887 | if (is_exe_or_dyn_lib) { | 1897 | if (is_exe_or_dyn_lib) { |
| 1888 | log.debug("queuing a job to build compiler_rt_lib", .{}); | 1898 | log.debug("queuing a job to build compiler_rt_lib", .{}); |
| 1889 | comp.job_queued_compiler_rt_lib = true; | 1899 | comp.job_queued_compiler_rt_lib = true; |
| ... | @@ -1895,8 +1905,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1895,8 +1905,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1895 | } | 1905 | } |
| 1896 | } | 1906 | } |
| 1897 | 1907 | ||
| 1898 | if (!comp.bin_file.options.skip_linker_dependencies and is_exe_or_dyn_lib and | 1908 | if (!comp.skip_linker_dependencies and is_exe_or_dyn_lib and |
| 1899 | !comp.bin_file.options.link_libc and capable_of_building_zig_libc) | 1909 | !comp.config.link_libc and capable_of_building_zig_libc) |
| 1900 | { | 1910 | { |
| 1901 | try comp.work_queue.writeItem(.{ .zig_libc = {} }); | 1911 | try comp.work_queue.writeItem(.{ .zig_libc = {} }); |
| 1902 | } | 1912 | } |
| ... | @@ -2425,7 +2435,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2425,7 +2435,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2425 | man.hash.add(comp.test_evented_io); | 2435 | man.hash.add(comp.test_evented_io); |
| 2426 | man.hash.addOptionalBytes(comp.test_filter); | 2436 | man.hash.addOptionalBytes(comp.test_filter); |
| 2427 | man.hash.addOptionalBytes(comp.test_name_prefix); | 2437 | man.hash.addOptionalBytes(comp.test_name_prefix); |
| 2428 | man.hash.add(comp.bin_file.options.skip_linker_dependencies); | 2438 | man.hash.add(comp.skip_linker_dependencies); |
| 2429 | man.hash.add(comp.formatted_panics); | 2439 | man.hash.add(comp.formatted_panics); |
| 2430 | man.hash.add(mod.emit_h != null); | 2440 | man.hash.add(mod.emit_h != null); |
| 2431 | man.hash.add(mod.error_limit); | 2441 | man.hash.add(mod.error_limit); |
| ... | @@ -2477,7 +2487,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2477,7 +2487,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2477 | man.hash.addListOfBytes(comp.bin_file.options.symbol_wrap_set.keys()); | 2487 | man.hash.addListOfBytes(comp.bin_file.options.symbol_wrap_set.keys()); |
| 2478 | man.hash.add(comp.bin_file.options.each_lib_rpath); | 2488 | man.hash.add(comp.bin_file.options.each_lib_rpath); |
| 2479 | man.hash.add(comp.bin_file.build_id); | 2489 | man.hash.add(comp.bin_file.build_id); |
| 2480 | man.hash.add(comp.bin_file.options.skip_linker_dependencies); | 2490 | man.hash.add(comp.skip_linker_dependencies); |
| 2481 | man.hash.add(comp.bin_file.options.z_nodelete); | 2491 | man.hash.add(comp.bin_file.options.z_nodelete); |
| 2482 | man.hash.add(comp.bin_file.options.z_notext); | 2492 | man.hash.add(comp.bin_file.options.z_notext); |
| 2483 | man.hash.add(comp.bin_file.options.z_defs); | 2493 | man.hash.add(comp.bin_file.options.z_defs); |
| ... | @@ -2489,7 +2499,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2489,7 +2499,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2489 | man.hash.add(comp.bin_file.options.z_max_page_size orelse 0); | 2499 | man.hash.add(comp.bin_file.options.z_max_page_size orelse 0); |
| 2490 | man.hash.add(comp.bin_file.options.hash_style); | 2500 | man.hash.add(comp.bin_file.options.hash_style); |
| 2491 | man.hash.add(comp.bin_file.options.compress_debug_sections); | 2501 | man.hash.add(comp.bin_file.options.compress_debug_sections); |
| 2492 | man.hash.add(comp.bin_file.options.include_compiler_rt); | 2502 | man.hash.add(comp.include_compiler_rt); |
| 2493 | man.hash.add(comp.bin_file.options.sort_section); | 2503 | man.hash.add(comp.bin_file.options.sort_section); |
| 2494 | if (comp.config.link_libc) { | 2504 | if (comp.config.link_libc) { |
| 2495 | man.hash.add(comp.bin_file.options.libc_installation != null); | 2505 | man.hash.add(comp.bin_file.options.libc_installation != null); |
| ... | @@ -3836,7 +3846,7 @@ pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest { | ... | @@ -3836,7 +3846,7 @@ pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest { |
| 3836 | // Also nothing that applies only to compiling .zig code. | 3846 | // Also nothing that applies only to compiling .zig code. |
| 3837 | man.hash.add(comp.sanitize_c); | 3847 | man.hash.add(comp.sanitize_c); |
| 3838 | man.hash.addListOfBytes(comp.clang_argv); | 3848 | man.hash.addListOfBytes(comp.clang_argv); |
| 3839 | man.hash.add(comp.bin_file.options.link_libcpp); | 3849 | man.hash.add(comp.config.link_libcpp); |
| 3840 | 3850 | ||
| 3841 | // When libc_installation is null it means that Zig generated this dir list | 3851 | // When libc_installation is null it means that Zig generated this dir list |
| 3842 | // based on the zig library directory alone. The zig lib directory file | 3852 | // based on the zig library directory alone. The zig lib directory file |
| ... | @@ -4909,7 +4919,7 @@ pub fn addCCArgs( | ... | @@ -4909,7 +4919,7 @@ pub fn addCCArgs( |
| 4909 | try argv.append("-fno-builtin"); | 4919 | try argv.append("-fno-builtin"); |
| 4910 | } | 4920 | } |
| 4911 | 4921 | ||
| 4912 | if (comp.bin_file.options.link_libcpp) { | 4922 | if (comp.config.link_libcpp) { |
| 4913 | const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{ | 4923 | const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{ |
| 4914 | comp.zig_lib_directory.path.?, "libcxx", "include", | 4924 | comp.zig_lib_directory.path.?, "libcxx", "include", |
| 4915 | }); | 4925 | }); |
| ... | @@ -4954,7 +4964,7 @@ pub fn addCCArgs( | ... | @@ -4954,7 +4964,7 @@ pub fn addCCArgs( |
| 4954 | try argv.append(libunwind_include_path); | 4964 | try argv.append(libunwind_include_path); |
| 4955 | } | 4965 | } |
| 4956 | 4966 | ||
| 4957 | if (comp.bin_file.options.link_libc and target.isGnuLibC()) { | 4967 | if (comp.config.link_libc and target.isGnuLibC()) { |
| 4958 | const target_version = target.os.version_range.linux.glibc; | 4968 | const target_version = target.os.version_range.linux.glibc; |
| 4959 | const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{ | 4969 | const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{ |
| 4960 | target_version.minor, | 4970 | target_version.minor, |
| ... | @@ -5944,7 +5954,7 @@ fn wantBuildLibCFromSource(comp: Compilation) bool { | ... | @@ -5944,7 +5954,7 @@ fn wantBuildLibCFromSource(comp: Compilation) bool { |
| 5944 | .Lib => comp.bin_file.options.link_mode == .Dynamic, | 5954 | .Lib => comp.bin_file.options.link_mode == .Dynamic, |
| 5945 | .Exe => true, | 5955 | .Exe => true, |
| 5946 | }; | 5956 | }; |
| 5947 | return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and | 5957 | return comp.config.link_libc and is_exe_or_dyn_lib and |
| 5948 | comp.bin_file.options.libc_installation == null and | 5958 | comp.bin_file.options.libc_installation == null and |
| 5949 | comp.bin_file.options.target.ofmt != .c; | 5959 | comp.bin_file.options.target.ofmt != .c; |
| 5950 | } | 5960 | } |
| ... | @@ -6164,6 +6174,7 @@ fn buildOutputFromZig( | ... | @@ -6164,6 +6174,7 @@ fn buildOutputFromZig( |
| 6164 | .have_zcu = true, | 6174 | .have_zcu = true, |
| 6165 | .emit_bin = true, | 6175 | .emit_bin = true, |
| 6166 | .root_optimize_mode = comp.compilerRtOptMode(), | 6176 | .root_optimize_mode = comp.compilerRtOptMode(), |
| 6177 | .link_libc = comp.config.link_libc, | ||
| 6167 | }); | 6178 | }); |
| 6168 | 6179 | ||
| 6169 | const root_mod = Package.Module.create(.{ | 6180 | const root_mod = Package.Module.create(.{ |
| ... | @@ -6224,7 +6235,6 @@ fn buildOutputFromZig( | ... | @@ -6224,7 +6235,6 @@ fn buildOutputFromZig( |
| 6224 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, | 6235 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 6225 | .clang_passthrough_mode = comp.clang_passthrough_mode, | 6236 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 6226 | .skip_linker_dependencies = true, | 6237 | .skip_linker_dependencies = true, |
| 6227 | .link_libc = comp.bin_file.options.link_libc, | ||
| 6228 | .want_structured_cfg = comp.bin_file.options.want_structured_cfg, | 6238 | .want_structured_cfg = comp.bin_file.options.want_structured_cfg, |
| 6229 | }); | 6239 | }); |
| 6230 | defer sub_compilation.destroy(); | 6240 | defer sub_compilation.destroy(); |
| ... | @@ -6305,7 +6315,6 @@ pub fn build_crt_file( | ... | @@ -6305,7 +6315,6 @@ pub fn build_crt_file( |
| 6305 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, | 6315 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 6306 | .clang_passthrough_mode = comp.clang_passthrough_mode, | 6316 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 6307 | .skip_linker_dependencies = true, | 6317 | .skip_linker_dependencies = true, |
| 6308 | .link_libc = comp.bin_file.options.link_libc, | ||
| 6309 | .want_structured_cfg = comp.bin_file.options.want_structured_cfg, | 6318 | .want_structured_cfg = comp.bin_file.options.want_structured_cfg, |
| 6310 | }); | 6319 | }); |
| 6311 | defer sub_compilation.destroy(); | 6320 | defer sub_compilation.destroy(); |
| ... | @@ -6327,7 +6336,7 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -6327,7 +6336,7 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { |
| 6327 | // This can happen when the user uses `build-exe foo.obj -lkernel32` and | 6336 | // This can happen when the user uses `build-exe foo.obj -lkernel32` and |
| 6328 | // then when we create a sub-Compilation for zig libc, it also tries to | 6337 | // then when we create a sub-Compilation for zig libc, it also tries to |
| 6329 | // build kernel32.lib. | 6338 | // build kernel32.lib. |
| 6330 | if (comp.bin_file.options.skip_linker_dependencies) return; | 6339 | if (comp.skip_linker_dependencies) return; |
| 6331 | 6340 | ||
| 6332 | // This happens when an `extern "foo"` function is referenced. | 6341 | // This happens when an `extern "foo"` function is referenced. |
| 6333 | // If we haven't seen this library yet and we're targeting Windows, we need | 6342 | // If we haven't seen this library yet and we're targeting Windows, we need |
src/Compilation/Config.zig+1-1| ... | @@ -335,7 +335,7 @@ pub fn resolve(options: Options) !Config { | ... | @@ -335,7 +335,7 @@ pub fn resolve(options: Options) !Config { |
| 335 | break :b .Static; | 335 | break :b .Static; |
| 336 | }; | 336 | }; |
| 337 | 337 | ||
| 338 | const import_memory = options.import_memory orelse false; | 338 | const import_memory = options.import_memory orelse (options.output_mode == .Obj); |
| 339 | const export_memory = b: { | 339 | const export_memory = b: { |
| 340 | if (link_mode == .Dynamic) { | 340 | if (link_mode == .Dynamic) { |
| 341 | if (options.export_memory == true) return error.ExportMemoryAndDynamicIncompatible; | 341 | if (options.export_memory == true) return error.ExportMemoryAndDynamicIncompatible; |
src/Sema.zig+15-12| ... | @@ -5742,7 +5742,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -5742,7 +5742,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5742 | const msg = try sema.errMsg(&child_block, src, "C import failed", .{}); | 5742 | const msg = try sema.errMsg(&child_block, src, "C import failed", .{}); |
| 5743 | errdefer msg.destroy(gpa); | 5743 | errdefer msg.destroy(gpa); |
| 5744 | 5744 | ||
| 5745 | if (!comp.bin_file.options.link_libc) | 5745 | if (!comp.config.link_libc) |
| 5746 | try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{}); | 5746 | try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{}); |
| 5747 | 5747 | ||
| 5748 | const gop = try mod.cimport_errors.getOrPut(gpa, sema.owner_decl_index); | 5748 | const gop = try mod.cimport_errors.getOrPut(gpa, sema.owner_decl_index); |
| ... | @@ -9058,7 +9058,7 @@ fn resolveGenericBody( | ... | @@ -9058,7 +9058,7 @@ fn resolveGenericBody( |
| 9058 | 9058 | ||
| 9059 | /// Given a library name, examines if the library name should end up in | 9059 | /// Given a library name, examines if the library name should end up in |
| 9060 | /// `link.File.Options.system_libs` table (for example, libc is always | 9060 | /// `link.File.Options.system_libs` table (for example, libc is always |
| 9061 | /// specified via dedicated flag `link.File.Options.link_libc` instead), | 9061 | /// specified via dedicated flag `link_libc` instead), |
| 9062 | /// and puts it there if it doesn't exist. | 9062 | /// and puts it there if it doesn't exist. |
| 9063 | /// It also dupes the library name which can then be saved as part of the | 9063 | /// It also dupes the library name which can then be saved as part of the |
| 9064 | /// respective `Decl` (either `ExternFn` or `Var`). | 9064 | /// respective `Decl` (either `ExternFn` or `Var`). |
| ... | @@ -9076,7 +9076,7 @@ fn handleExternLibName( | ... | @@ -9076,7 +9076,7 @@ fn handleExternLibName( |
| 9076 | const target = mod.getTarget(); | 9076 | const target = mod.getTarget(); |
| 9077 | log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); | 9077 | log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); |
| 9078 | if (target.is_libc_lib_name(lib_name)) { | 9078 | if (target.is_libc_lib_name(lib_name)) { |
| 9079 | if (!comp.bin_file.options.link_libc) { | 9079 | if (!comp.config.link_libc) { |
| 9080 | return sema.fail( | 9080 | return sema.fail( |
| 9081 | block, | 9081 | block, |
| 9082 | src_loc, | 9082 | src_loc, |
| ... | @@ -9087,18 +9087,21 @@ fn handleExternLibName( | ... | @@ -9087,18 +9087,21 @@ fn handleExternLibName( |
| 9087 | break :blk; | 9087 | break :blk; |
| 9088 | } | 9088 | } |
| 9089 | if (target.is_libcpp_lib_name(lib_name)) { | 9089 | if (target.is_libcpp_lib_name(lib_name)) { |
| 9090 | if (!comp.bin_file.options.link_libcpp) { | 9090 | if (!comp.config.link_libcpp) return sema.fail( |
| 9091 | return sema.fail( | 9091 | block, |
| 9092 | block, | 9092 | src_loc, |
| 9093 | src_loc, | 9093 | "dependency on libc++ must be explicitly specified in the build command", |
| 9094 | "dependency on libc++ must be explicitly specified in the build command", | 9094 | .{}, |
| 9095 | .{}, | 9095 | ); |
| 9096 | ); | ||
| 9097 | } | ||
| 9098 | break :blk; | 9096 | break :blk; |
| 9099 | } | 9097 | } |
| 9100 | if (mem.eql(u8, lib_name, "unwind")) { | 9098 | if (mem.eql(u8, lib_name, "unwind")) { |
| 9101 | comp.bin_file.options.link_libunwind = true; | 9099 | if (!comp.config.link_libunwind) return sema.fail( |
| 9100 | block, | ||
| 9101 | src_loc, | ||
| 9102 | "dependency on libunwind must be explicitly specified in the build command", | ||
| 9103 | .{}, | ||
| 9104 | ); | ||
| 9102 | break :blk; | 9105 | break :blk; |
| 9103 | } | 9106 | } |
| 9104 | if (!target.isWasm() and !comp.bin_file.options.pic) { | 9107 | if (!target.isWasm() and !comp.bin_file.options.pic) { |
src/codegen/llvm.zig+1-3| ... | @@ -3083,9 +3083,7 @@ pub const Object = struct { | ... | @@ -3083,9 +3083,7 @@ pub const Object = struct { |
| 3083 | if (comp.unwind_tables) { | 3083 | if (comp.unwind_tables) { |
| 3084 | try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder); | 3084 | try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder); |
| 3085 | } | 3085 | } |
| 3086 | if (comp.bin_file.options.skip_linker_dependencies or | 3086 | if (comp.skip_linker_dependencies or comp.bin_file.options.no_builtin) { |
| 3087 | comp.bin_file.options.no_builtin) | ||
| 3088 | { | ||
| 3089 | // The intent here is for compiler-rt and libc functions to not generate | 3087 | // The intent here is for compiler-rt and libc functions to not generate |
| 3090 | // infinite recursion. For example, if we are compiling the memcpy function, | 3088 | // infinite recursion. For example, if we are compiling the memcpy function, |
| 3091 | // and llvm detects that the body is equivalent to memcpy, it may replace the | 3089 | // and llvm detects that the body is equivalent to memcpy, it may replace the |
src/libtsan.zig+1-1| ... | @@ -119,7 +119,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { | ... | @@ -119,7 +119,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 119 | }); | 119 | }); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | const to_c_or_not_to_c_sources = if (comp.bin_file.options.link_libc) | 122 | const to_c_or_not_to_c_sources = if (comp.config.link_libc) |
| 123 | &sanitizer_libcdep_sources | 123 | &sanitizer_libcdep_sources |
| 124 | else | 124 | else |
| 125 | &sanitizer_nolibc_sources; | 125 | &sanitizer_nolibc_sources; |
src/link.zig+1-2| ... | @@ -133,7 +133,6 @@ pub const File = struct { | ... | @@ -133,7 +133,6 @@ pub const File = struct { |
| 133 | export_symbol_names: []const []const u8, | 133 | export_symbol_names: []const []const u8, |
| 134 | global_base: ?u64, | 134 | global_base: ?u64, |
| 135 | dll_export_fns: bool, | 135 | dll_export_fns: bool, |
| 136 | skip_linker_dependencies: bool, | ||
| 137 | parent_compilation_link_libc: bool, | 136 | parent_compilation_link_libc: bool, |
| 138 | each_lib_rpath: bool, | 137 | each_lib_rpath: bool, |
| 139 | build_id: std.zig.BuildId, | 138 | build_id: std.zig.BuildId, |
| ... | @@ -1099,7 +1098,7 @@ pub const File = struct { | ... | @@ -1099,7 +1098,7 @@ pub const File = struct { |
| 1099 | } | 1098 | } |
| 1100 | 1099 | ||
| 1101 | pub fn isStatic(self: File) bool { | 1100 | pub fn isStatic(self: File) bool { |
| 1102 | return self.base.comp.config.link_mode == .Static; | 1101 | return self.comp.config.link_mode == .Static; |
| 1103 | } | 1102 | } |
| 1104 | 1103 | ||
| 1105 | pub fn isObject(self: File) bool { | 1104 | pub fn isObject(self: File) bool { |
src/link/Coff/lld.zig+47-47| ... | @@ -48,7 +48,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -48,7 +48,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 48 | const is_lib = self.base.comp.config.output_mode == .Lib; | 48 | const is_lib = self.base.comp.config.output_mode == .Lib; |
| 49 | const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib; | 49 | const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib; |
| 50 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.comp.config.output_mode == .Exe; | 50 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.comp.config.output_mode == .Exe; |
| 51 | const link_in_crt = self.base.options.link_libc and is_exe_or_dyn_lib; | 51 | const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib; |
| 52 | const target = self.base.comp.root_mod.resolved_target.result; | 52 | const target = self.base.comp.root_mod.resolved_target.result; |
| 53 | const optimize_mode = self.base.comp.root_mod.optimize_mode; | 53 | const optimize_mode = self.base.comp.root_mod.optimize_mode; |
| 54 | 54 | ||
| ... | @@ -56,17 +56,17 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -56,17 +56,17 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 56 | const id_symlink_basename = "lld.id"; | 56 | const id_symlink_basename = "lld.id"; |
| 57 | 57 | ||
| 58 | var man: Cache.Manifest = undefined; | 58 | var man: Cache.Manifest = undefined; |
| 59 | defer if (!self.base.options.disable_lld_caching) man.deinit(); | 59 | defer if (!self.base.disable_lld_caching) man.deinit(); |
| 60 | 60 | ||
| 61 | var digest: [Cache.hex_digest_len]u8 = undefined; | 61 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 62 | 62 | ||
| 63 | if (!self.base.options.disable_lld_caching) { | 63 | if (!self.base.disable_lld_caching) { |
| 64 | man = comp.cache_parent.obtain(); | 64 | man = comp.cache_parent.obtain(); |
| 65 | self.base.releaseLock(); | 65 | self.base.releaseLock(); |
| 66 | 66 | ||
| 67 | comptime assert(Compilation.link_hash_implementation_version == 10); | 67 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 68 | 68 | ||
| 69 | for (self.base.options.objects) |obj| { | 69 | for (comp.objects) |obj| { |
| 70 | _ = try man.addFile(obj.path, null); | 70 | _ = try man.addFile(obj.path, null); |
| 71 | man.hash.add(obj.must_link); | 71 | man.hash.add(obj.must_link); |
| 72 | } | 72 | } |
| ... | @@ -79,12 +79,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -79,12 +79,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 79 | } | 79 | } |
| 80 | } | 80 | } |
| 81 | try man.addOptionalFile(module_obj_path); | 81 | try man.addOptionalFile(module_obj_path); |
| 82 | man.hash.addOptionalBytes(self.base.options.entry); | 82 | man.hash.addOptionalBytes(comp.config.entry); |
| 83 | man.hash.add(self.base.stack_size); | 83 | man.hash.add(self.base.stack_size); |
| 84 | man.hash.addOptional(self.image_base); | 84 | man.hash.addOptional(self.image_base); |
| 85 | man.hash.addListOfBytes(self.base.options.lib_dirs); | 85 | man.hash.addListOfBytes(self.lib_dirs); |
| 86 | man.hash.add(self.base.options.skip_linker_dependencies); | 86 | man.hash.add(comp.skip_linker_dependencies); |
| 87 | if (self.base.options.link_libc) { | 87 | if (comp.config.link_libc) { |
| 88 | man.hash.add(self.base.comp.libc_installation != null); | 88 | man.hash.add(self.base.comp.libc_installation != null); |
| 89 | if (self.base.comp.libc_installation) |libc_installation| { | 89 | if (self.base.comp.libc_installation) |libc_installation| { |
| 90 | man.hash.addBytes(libc_installation.crt_dir.?); | 90 | man.hash.addBytes(libc_installation.crt_dir.?); |
| ... | @@ -95,18 +95,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -95,18 +95,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | try link.hashAddSystemLibs(&man, self.base.comp.system_libs); | 97 | try link.hashAddSystemLibs(&man, self.base.comp.system_libs); |
| 98 | man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys()); | 98 | man.hash.addListOfBytes(self.base.force_undefined_symbols.keys()); |
| 99 | man.hash.addOptional(self.base.options.subsystem); | 99 | man.hash.addOptional(self.subsystem); |
| 100 | man.hash.add(self.base.options.is_test); | 100 | man.hash.add(comp.config.is_test); |
| 101 | man.hash.add(self.base.options.tsaware); | 101 | man.hash.add(self.tsaware); |
| 102 | man.hash.add(self.base.options.nxcompat); | 102 | man.hash.add(self.nxcompat); |
| 103 | man.hash.add(self.base.options.dynamicbase); | 103 | man.hash.add(self.dynamicbase); |
| 104 | man.hash.addOptional(self.base.allow_shlib_undefined); | 104 | man.hash.addOptional(self.base.allow_shlib_undefined); |
| 105 | // strip does not need to go into the linker hash because it is part of the hash namespace | 105 | // strip does not need to go into the linker hash because it is part of the hash namespace |
| 106 | man.hash.addOptional(self.base.options.major_subsystem_version); | 106 | man.hash.addOptional(self.major_subsystem_version); |
| 107 | man.hash.addOptional(self.base.options.minor_subsystem_version); | 107 | man.hash.addOptional(self.minor_subsystem_version); |
| 108 | man.hash.addOptional(self.base.options.version); | 108 | man.hash.addOptional(comp.version); |
| 109 | try man.addOptionalFile(self.base.options.module_definition_file); | 109 | try man.addOptionalFile(self.module_definition_file); |
| 110 | 110 | ||
| 111 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. | 111 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 112 | _ = try man.hit(); | 112 | _ = try man.hit(); |
| ... | @@ -141,8 +141,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -141,8 +141,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 141 | // here. TODO: think carefully about how we can avoid this redundant operation when doing | 141 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 142 | // build-obj. See also the corresponding TODO in linkAsArchive. | 142 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 143 | const the_object_path = blk: { | 143 | const the_object_path = blk: { |
| 144 | if (self.base.options.objects.len != 0) | 144 | if (comp.objects.len != 0) |
| 145 | break :blk self.base.options.objects[0].path; | 145 | break :blk comp.objects[0].path; |
| 146 | 146 | ||
| 147 | if (comp.c_object_table.count() != 0) | 147 | if (comp.c_object_table.count() != 0) |
| 148 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 148 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -171,21 +171,21 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -171,21 +171,21 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 171 | 171 | ||
| 172 | try argv.append("-ERRORLIMIT:0"); | 172 | try argv.append("-ERRORLIMIT:0"); |
| 173 | try argv.append("-NOLOGO"); | 173 | try argv.append("-NOLOGO"); |
| 174 | if (!self.base.options.strip) { | 174 | if (self.base.debug_format != .strip) { |
| 175 | try argv.append("-DEBUG"); | 175 | try argv.append("-DEBUG"); |
| 176 | 176 | ||
| 177 | const out_ext = std.fs.path.extension(full_out_path); | 177 | const out_ext = std.fs.path.extension(full_out_path); |
| 178 | const out_pdb = self.base.options.pdb_out_path orelse try allocPrint(arena, "{s}.pdb", .{ | 178 | const out_pdb = self.pdb_out_path orelse try allocPrint(arena, "{s}.pdb", .{ |
| 179 | full_out_path[0 .. full_out_path.len - out_ext.len], | 179 | full_out_path[0 .. full_out_path.len - out_ext.len], |
| 180 | }); | 180 | }); |
| 181 | 181 | ||
| 182 | try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb})); | 182 | try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb})); |
| 183 | try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb})); | 183 | try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb})); |
| 184 | } | 184 | } |
| 185 | if (self.base.options.version) |version| { | 185 | if (comp.version) |version| { |
| 186 | try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor })); | 186 | try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor })); |
| 187 | } | 187 | } |
| 188 | if (self.base.options.lto) { | 188 | if (comp.config.lto) { |
| 189 | switch (optimize_mode) { | 189 | switch (optimize_mode) { |
| 190 | .Debug => {}, | 190 | .Debug => {}, |
| 191 | .ReleaseSmall => try argv.append("-OPT:lldlto=2"), | 191 | .ReleaseSmall => try argv.append("-OPT:lldlto=2"), |
| ... | @@ -209,7 +209,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -209,7 +209,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 209 | } | 209 | } |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | for (self.base.options.force_undefined_symbols.keys()) |symbol| { | 212 | for (self.base.force_undefined_symbols.keys()) |symbol| { |
| 213 | try argv.append(try allocPrint(arena, "-INCLUDE:{s}", .{symbol})); | 213 | try argv.append(try allocPrint(arena, "-INCLUDE:{s}", .{symbol})); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| ... | @@ -217,17 +217,17 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -217,17 +217,17 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 217 | try argv.append("-DLL"); | 217 | try argv.append("-DLL"); |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | if (self.base.options.entry) |entry| { | 220 | if (comp.config.entry) |entry| { |
| 221 | try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{entry})); | 221 | try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{entry})); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | if (self.base.options.tsaware) { | 224 | if (self.tsaware) { |
| 225 | try argv.append("-tsaware"); | 225 | try argv.append("-tsaware"); |
| 226 | } | 226 | } |
| 227 | if (self.base.options.nxcompat) { | 227 | if (self.nxcompat) { |
| 228 | try argv.append("-nxcompat"); | 228 | try argv.append("-nxcompat"); |
| 229 | } | 229 | } |
| 230 | if (!self.base.options.dynamicbase) { | 230 | if (!self.dynamicbase) { |
| 231 | try argv.append("-dynamicbase:NO"); | 231 | try argv.append("-dynamicbase:NO"); |
| 232 | } | 232 | } |
| 233 | if (self.base.allow_shlib_undefined) { | 233 | if (self.base.allow_shlib_undefined) { |
| ... | @@ -236,12 +236,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -236,12 +236,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 236 | 236 | ||
| 237 | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); | 237 | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); |
| 238 | 238 | ||
| 239 | if (self.base.options.implib_emit) |emit| { | 239 | if (self.implib_emit) |emit| { |
| 240 | const implib_out_path = try emit.directory.join(arena, &[_][]const u8{emit.sub_path}); | 240 | const implib_out_path = try emit.directory.join(arena, &[_][]const u8{emit.sub_path}); |
| 241 | try argv.append(try allocPrint(arena, "-IMPLIB:{s}", .{implib_out_path})); | 241 | try argv.append(try allocPrint(arena, "-IMPLIB:{s}", .{implib_out_path})); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | if (self.base.options.link_libc) { | 244 | if (comp.config.link_libc) { |
| 245 | if (self.base.comp.libc_installation) |libc_installation| { | 245 | if (self.base.comp.libc_installation) |libc_installation| { |
| 246 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?})); | 246 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?})); |
| 247 | 247 | ||
| ... | @@ -252,12 +252,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -252,12 +252,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 252 | } | 252 | } |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | for (self.base.options.lib_dirs) |lib_dir| { | 255 | for (self.lib_dirs) |lib_dir| { |
| 256 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); | 256 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | try argv.ensureUnusedCapacity(self.base.options.objects.len); | 259 | try argv.ensureUnusedCapacity(comp.objects.len); |
| 260 | for (self.base.options.objects) |obj| { | 260 | for (comp.objects) |obj| { |
| 261 | if (obj.must_link) { | 261 | if (obj.must_link) { |
| 262 | argv.appendAssumeCapacity(try allocPrint(arena, "-WHOLEARCHIVE:{s}", .{obj.path})); | 262 | argv.appendAssumeCapacity(try allocPrint(arena, "-WHOLEARCHIVE:{s}", .{obj.path})); |
| 263 | } else { | 263 | } else { |
| ... | @@ -279,18 +279,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -279,18 +279,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 279 | try argv.append(p); | 279 | try argv.append(p); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | if (self.base.options.module_definition_file) |def| { | 282 | if (self.module_definition_file) |def| { |
| 283 | try argv.append(try allocPrint(arena, "-DEF:{s}", .{def})); | 283 | try argv.append(try allocPrint(arena, "-DEF:{s}", .{def})); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | const resolved_subsystem: ?std.Target.SubSystem = blk: { | 286 | const resolved_subsystem: ?std.Target.SubSystem = blk: { |
| 287 | if (self.base.options.subsystem) |explicit| break :blk explicit; | 287 | if (self.subsystem) |explicit| break :blk explicit; |
| 288 | switch (target.os.tag) { | 288 | switch (target.os.tag) { |
| 289 | .windows => { | 289 | .windows => { |
| 290 | if (self.base.comp.module) |module| { | 290 | if (self.base.comp.module) |module| { |
| 291 | if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib) | 291 | if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib) |
| 292 | break :blk null; | 292 | break :blk null; |
| 293 | if (module.stage1_flags.have_c_main or self.base.options.is_test or | 293 | if (module.stage1_flags.have_c_main or comp.config.is_test or |
| 294 | module.stage1_flags.have_winmain_crt_startup or | 294 | module.stage1_flags.have_winmain_crt_startup or |
| 295 | module.stage1_flags.have_wwinmain_crt_startup) | 295 | module.stage1_flags.have_wwinmain_crt_startup) |
| 296 | { | 296 | { |
| ... | @@ -310,8 +310,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -310,8 +310,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 310 | const mode: Mode = mode: { | 310 | const mode: Mode = mode: { |
| 311 | if (resolved_subsystem) |subsystem| { | 311 | if (resolved_subsystem) |subsystem| { |
| 312 | const subsystem_suffix = ss: { | 312 | const subsystem_suffix = ss: { |
| 313 | if (self.base.options.major_subsystem_version) |major| { | 313 | if (self.major_subsystem_version) |major| { |
| 314 | if (self.base.options.minor_subsystem_version) |minor| { | 314 | if (self.minor_subsystem_version) |minor| { |
| 315 | break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor }); | 315 | break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor }); |
| 316 | } else { | 316 | } else { |
| 317 | break :ss try allocPrint(arena, ",{d}", .{major}); | 317 | break :ss try allocPrint(arena, ",{d}", .{major}); |
| ... | @@ -447,7 +447,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -447,7 +447,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 447 | } | 447 | } |
| 448 | } else { | 448 | } else { |
| 449 | try argv.append("-NODEFAULTLIB"); | 449 | try argv.append("-NODEFAULTLIB"); |
| 450 | if (!is_lib and self.base.options.entry == null) { | 450 | if (!is_lib and comp.config.entry == null) { |
| 451 | if (self.base.comp.module) |module| { | 451 | if (self.base.comp.module) |module| { |
| 452 | if (module.stage1_flags.have_winmain_crt_startup) { | 452 | if (module.stage1_flags.have_winmain_crt_startup) { |
| 453 | try argv.append("-ENTRY:WinMainCRTStartup"); | 453 | try argv.append("-ENTRY:WinMainCRTStartup"); |
| ... | @@ -463,18 +463,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -463,18 +463,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | // libc++ dep | 465 | // libc++ dep |
| 466 | if (self.base.options.link_libcpp) { | 466 | if (comp.config.link_libcpp) { |
| 467 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); | 467 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 468 | try argv.append(comp.libcxx_static_lib.?.full_object_path); | 468 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | // libunwind dep | 471 | // libunwind dep |
| 472 | if (self.base.options.link_libunwind) { | 472 | if (comp.config.link_libunwind) { |
| 473 | try argv.append(comp.libunwind_static_lib.?.full_object_path); | 473 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 474 | } | 474 | } |
| 475 | 475 | ||
| 476 | if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies) { | 476 | if (is_exe_or_dyn_lib and !comp.skip_linker_dependencies) { |
| 477 | if (!self.base.options.link_libc) { | 477 | if (!comp.config.link_libc) { |
| 478 | if (comp.libc_static_lib) |lib| { | 478 | if (comp.libc_static_lib) |lib| { |
| 479 | try argv.append(lib.full_object_path); | 479 | try argv.append(lib.full_object_path); |
| 480 | } | 480 | } |
| ... | @@ -492,13 +492,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -492,13 +492,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 492 | argv.appendAssumeCapacity(crt_file.full_object_path); | 492 | argv.appendAssumeCapacity(crt_file.full_object_path); |
| 493 | continue; | 493 | continue; |
| 494 | } | 494 | } |
| 495 | if (try findLib(arena, lib_basename, self.base.options.lib_dirs)) |full_path| { | 495 | if (try findLib(arena, lib_basename, self.lib_dirs)) |full_path| { |
| 496 | argv.appendAssumeCapacity(full_path); | 496 | argv.appendAssumeCapacity(full_path); |
| 497 | continue; | 497 | continue; |
| 498 | } | 498 | } |
| 499 | if (target.abi.isGnu()) { | 499 | if (target.abi.isGnu()) { |
| 500 | const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key}); | 500 | const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key}); |
| 501 | if (try findLib(arena, fallback_name, self.base.options.lib_dirs)) |full_path| { | 501 | if (try findLib(arena, fallback_name, self.lib_dirs)) |full_path| { |
| 502 | argv.appendAssumeCapacity(full_path); | 502 | argv.appendAssumeCapacity(full_path); |
| 503 | continue; | 503 | continue; |
| 504 | } | 504 | } |
| ... | @@ -582,7 +582,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -582,7 +582,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 582 | } | 582 | } |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | if (!self.base.options.disable_lld_caching) { | 585 | if (!self.base.disable_lld_caching) { |
| 586 | // Update the file with the digest. If it fails we can continue; it only | 586 | // Update the file with the digest. If it fails we can continue; it only |
| 587 | // means that the next invocation will have an unnecessary cache miss. | 587 | // means that the next invocation will have an unnecessary cache miss. |
| 588 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { | 588 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { |
src/link/Dwarf.zig+6-4| ... | @@ -1022,16 +1022,18 @@ const min_nop_size = 2; | ... | @@ -1022,16 +1022,18 @@ const min_nop_size = 2; |
| 1022 | /// actual_capacity + (actual_capacity / ideal_factor) | 1022 | /// actual_capacity + (actual_capacity / ideal_factor) |
| 1023 | const ideal_factor = 3; | 1023 | const ideal_factor = 3; |
| 1024 | 1024 | ||
| 1025 | pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf { | 1025 | pub fn init(lf: *File, format: Format) Dwarf { |
| 1026 | const target = &bin_file.options.target; | 1026 | const comp = lf.comp; |
| 1027 | const gpa = comp.gpa; | ||
| 1028 | const target = comp.root_mod.resolved_target.result; | ||
| 1027 | const ptr_width: PtrWidth = switch (target.ptrBitWidth()) { | 1029 | const ptr_width: PtrWidth = switch (target.ptrBitWidth()) { |
| 1028 | 0...32 => .p32, | 1030 | 0...32 => .p32, |
| 1029 | 33...64 => .p64, | 1031 | 33...64 => .p64, |
| 1030 | else => unreachable, | 1032 | else => unreachable, |
| 1031 | }; | 1033 | }; |
| 1032 | return .{ | 1034 | return .{ |
| 1033 | .allocator = allocator, | 1035 | .allocator = gpa, |
| 1034 | .bin_file = bin_file, | 1036 | .bin_file = lf, |
| 1035 | .format = format, | 1037 | .format = format, |
| 1036 | .ptr_width = ptr_width, | 1038 | .ptr_width = ptr_width, |
| 1037 | .dbg_line_header = switch (target.cpu.arch) { | 1039 | .dbg_line_header = switch (target.cpu.arch) { |
src/link/Elf.zig+146-149| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | base: link.File, | 1 | base: link.File, |
| 2 | image_base: u64, | 2 | image_base: u64, |
| 3 | rdynamic: bool, | ||
| 3 | 4 | ||
| 4 | ptr_width: PtrWidth, | 5 | ptr_width: PtrWidth, |
| 5 | 6 | ||
| ... | @@ -358,19 +359,21 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf { | ... | @@ -358,19 +359,21 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 358 | .debug_format = options.debug_format orelse .{ .dwarf = .@"32" }, | 359 | .debug_format = options.debug_format orelse .{ .dwarf = .@"32" }, |
| 359 | .function_sections = options.function_sections, | 360 | .function_sections = options.function_sections, |
| 360 | .data_sections = options.data_sections, | 361 | .data_sections = options.data_sections, |
| 361 | |||
| 362 | .image_base = b: { | ||
| 363 | if (is_dyn_lib) break :b 0; | ||
| 364 | if (output_mode == .Exe and comp.config.pie) return 0; | ||
| 365 | return options.image_base orelse switch (ptr_width) { | ||
| 366 | .p32 => 0x1000, | ||
| 367 | .p64 => 0x1000000, | ||
| 368 | }; | ||
| 369 | }, | ||
| 370 | }, | 362 | }, |
| 371 | .ptr_width = ptr_width, | 363 | .ptr_width = ptr_width, |
| 372 | .page_size = page_size, | 364 | .page_size = page_size, |
| 373 | .default_sym_version = default_sym_version, | 365 | .default_sym_version = default_sym_version, |
| 366 | |||
| 367 | .image_base = b: { | ||
| 368 | if (is_dyn_lib) break :b 0; | ||
| 369 | if (output_mode == .Exe and comp.config.pie) break :b 0; | ||
| 370 | break :b options.image_base orelse switch (ptr_width) { | ||
| 371 | .p32 => 0x1000, | ||
| 372 | .p64 => 0x1000000, | ||
| 373 | }; | ||
| 374 | }, | ||
| 375 | |||
| 376 | .rdynamic = options.rdynamic, | ||
| 374 | }; | 377 | }; |
| 375 | if (use_llvm and comp.config.have_zcu) { | 378 | if (use_llvm and comp.config.have_zcu) { |
| 376 | self.llvm_object = try LlvmObject.create(arena, options); | 379 | self.llvm_object = try LlvmObject.create(arena, options); |
| ... | @@ -1006,7 +1009,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1006,7 +1009,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1006 | break :blk path; | 1009 | break :blk path; |
| 1007 | } | 1010 | } |
| 1008 | } else null; | 1011 | } else null; |
| 1009 | const gc_sections = self.base.gc_sections; | ||
| 1010 | 1012 | ||
| 1011 | // --verbose-link | 1013 | // --verbose-link |
| 1012 | if (self.base.comp.verbose_link) try self.dumpArgv(comp); | 1014 | if (self.base.comp.verbose_link) try self.dumpArgv(comp); |
| ... | @@ -1047,14 +1049,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1047,14 +1049,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1047 | var rpath_table = std.StringArrayHashMap(void).init(gpa); | 1049 | var rpath_table = std.StringArrayHashMap(void).init(gpa); |
| 1048 | defer rpath_table.deinit(); | 1050 | defer rpath_table.deinit(); |
| 1049 | 1051 | ||
| 1050 | for (self.base.options.rpath_list) |rpath| { | 1052 | for (self.base.rpath_list) |rpath| { |
| 1051 | _ = try rpath_table.put(rpath, {}); | 1053 | _ = try rpath_table.put(rpath, {}); |
| 1052 | } | 1054 | } |
| 1053 | 1055 | ||
| 1054 | if (self.base.options.each_lib_rpath) { | 1056 | if (self.each_lib_rpath) { |
| 1055 | var test_path = std.ArrayList(u8).init(gpa); | 1057 | var test_path = std.ArrayList(u8).init(gpa); |
| 1056 | defer test_path.deinit(); | 1058 | defer test_path.deinit(); |
| 1057 | for (self.base.options.lib_dirs) |lib_dir_path| { | 1059 | for (self.lib_dirs) |lib_dir_path| { |
| 1058 | for (self.base.comp.system_libs.keys()) |link_lib| { | 1060 | for (self.base.comp.system_libs.keys()) |link_lib| { |
| 1059 | if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic))) | 1061 | if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic))) |
| 1060 | continue; | 1062 | continue; |
| ... | @@ -1076,9 +1078,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1076,9 +1078,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1076 | } | 1078 | } |
| 1077 | 1079 | ||
| 1078 | // libc | 1080 | // libc |
| 1079 | if (!self.base.options.skip_linker_dependencies and | 1081 | if (!comp.skip_linker_dependencies and !comp.config.link_libc) { |
| 1080 | !self.base.options.link_libc) | ||
| 1081 | { | ||
| 1082 | if (comp.libc_static_lib) |lib| { | 1082 | if (comp.libc_static_lib) |lib| { |
| 1083 | try positionals.append(.{ .path = lib.full_object_path }); | 1083 | try positionals.append(.{ .path = lib.full_object_path }); |
| 1084 | } | 1084 | } |
| ... | @@ -1263,10 +1263,10 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1263,10 +1263,10 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1263 | self.entry_index = if (entry) |name| self.globalByName(name) else null; | 1263 | self.entry_index = if (entry) |name| self.globalByName(name) else null; |
| 1264 | } | 1264 | } |
| 1265 | 1265 | ||
| 1266 | if (gc_sections) { | 1266 | if (self.base.gc_sections) { |
| 1267 | try gc.gcAtoms(self); | 1267 | try gc.gcAtoms(self); |
| 1268 | 1268 | ||
| 1269 | if (self.base.options.print_gc_sections) { | 1269 | if (self.base.print_gc_sections) { |
| 1270 | try gc.dumpPrunedAtoms(self); | 1270 | try gc.dumpPrunedAtoms(self); |
| 1271 | } | 1271 | } |
| 1272 | } | 1272 | } |
| ... | @@ -1347,13 +1347,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1347,13 +1347,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1347 | } | 1347 | } |
| 1348 | 1348 | ||
| 1349 | pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void { | 1349 | pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void { |
| 1350 | const gpa = self.base.comp.gpa; | 1350 | const gpa = comp.gpa; |
| 1351 | 1351 | ||
| 1352 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); | 1352 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 1353 | defer positionals.deinit(); | 1353 | defer positionals.deinit(); |
| 1354 | 1354 | ||
| 1355 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); | 1355 | try positionals.ensureUnusedCapacity(comp.objects.len); |
| 1356 | positionals.appendSliceAssumeCapacity(self.base.options.objects); | 1356 | positionals.appendSliceAssumeCapacity(comp.objects); |
| 1357 | 1357 | ||
| 1358 | // This is a set of object files emitted by clang in a single `build-exe` invocation. | 1358 | // This is a set of object files emitted by clang in a single `build-exe` invocation. |
| 1359 | // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up | 1359 | // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up |
| ... | @@ -1495,8 +1495,8 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) | ... | @@ -1495,8 +1495,8 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) |
| 1495 | 1495 | ||
| 1496 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); | 1496 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 1497 | defer positionals.deinit(); | 1497 | defer positionals.deinit(); |
| 1498 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); | 1498 | try positionals.ensureUnusedCapacity(comp.objects.len); |
| 1499 | positionals.appendSliceAssumeCapacity(self.base.options.objects); | 1499 | positionals.appendSliceAssumeCapacity(comp.objects); |
| 1500 | 1500 | ||
| 1501 | // This is a set of object files emitted by clang in a single `build-exe` invocation. | 1501 | // This is a set of object files emitted by clang in a single `build-exe` invocation. |
| 1502 | // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up | 1502 | // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up |
| ... | @@ -1606,7 +1606,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1606,7 +1606,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1606 | try argv.append(full_out_path); | 1606 | try argv.append(full_out_path); |
| 1607 | 1607 | ||
| 1608 | if (self.base.isRelocatable()) { | 1608 | if (self.base.isRelocatable()) { |
| 1609 | for (self.base.options.objects) |obj| { | 1609 | for (comp.objects) |obj| { |
| 1610 | try argv.append(obj.path); | 1610 | try argv.append(obj.path); |
| 1611 | } | 1611 | } |
| 1612 | 1612 | ||
| ... | @@ -1626,28 +1626,28 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1626,28 +1626,28 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1626 | } | 1626 | } |
| 1627 | 1627 | ||
| 1628 | if (self.base.isDynLib()) { | 1628 | if (self.base.isDynLib()) { |
| 1629 | if (self.base.options.soname) |name| { | 1629 | if (self.soname) |name| { |
| 1630 | try argv.append("-soname"); | 1630 | try argv.append("-soname"); |
| 1631 | try argv.append(name); | 1631 | try argv.append(name); |
| 1632 | } | 1632 | } |
| 1633 | } | 1633 | } |
| 1634 | 1634 | ||
| 1635 | if (self.base.options.entry) |entry| { | 1635 | if (comp.config.entry) |entry| { |
| 1636 | try argv.append("--entry"); | 1636 | try argv.append("--entry"); |
| 1637 | try argv.append(entry); | 1637 | try argv.append(entry); |
| 1638 | } | 1638 | } |
| 1639 | 1639 | ||
| 1640 | for (self.base.options.rpath_list) |rpath| { | 1640 | for (self.base.rpath_list) |rpath| { |
| 1641 | try argv.append("-rpath"); | 1641 | try argv.append("-rpath"); |
| 1642 | try argv.append(rpath); | 1642 | try argv.append(rpath); |
| 1643 | } | 1643 | } |
| 1644 | 1644 | ||
| 1645 | if (self.base.options.each_lib_rpath) { | 1645 | if (self.each_lib_rpath) { |
| 1646 | for (self.base.options.lib_dirs) |lib_dir_path| { | 1646 | for (self.lib_dirs) |lib_dir_path| { |
| 1647 | try argv.append("-rpath"); | 1647 | try argv.append("-rpath"); |
| 1648 | try argv.append(lib_dir_path); | 1648 | try argv.append(lib_dir_path); |
| 1649 | } | 1649 | } |
| 1650 | for (self.base.options.objects) |obj| { | 1650 | for (comp.objects) |obj| { |
| 1651 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { | 1651 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| 1652 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; | 1652 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| 1653 | if (obj.loption) continue; | 1653 | if (obj.loption) continue; |
| ... | @@ -1669,29 +1669,29 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1669,29 +1669,29 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1669 | try argv.append("--gc-sections"); | 1669 | try argv.append("--gc-sections"); |
| 1670 | } | 1670 | } |
| 1671 | 1671 | ||
| 1672 | if (self.base.options.print_gc_sections) { | 1672 | if (self.base.print_gc_sections) { |
| 1673 | try argv.append("--print-gc-sections"); | 1673 | try argv.append("--print-gc-sections"); |
| 1674 | } | 1674 | } |
| 1675 | 1675 | ||
| 1676 | if (self.base.options.eh_frame_hdr) { | 1676 | if (self.eh_frame_hdr) { |
| 1677 | try argv.append("--eh-frame-hdr"); | 1677 | try argv.append("--eh-frame-hdr"); |
| 1678 | } | 1678 | } |
| 1679 | 1679 | ||
| 1680 | if (self.base.options.rdynamic) { | 1680 | if (self.rdynamic) { |
| 1681 | try argv.append("--export-dynamic"); | 1681 | try argv.append("--export-dynamic"); |
| 1682 | } | 1682 | } |
| 1683 | 1683 | ||
| 1684 | if (self.base.options.z_notext) { | 1684 | if (self.z_notext) { |
| 1685 | try argv.append("-z"); | 1685 | try argv.append("-z"); |
| 1686 | try argv.append("notext"); | 1686 | try argv.append("notext"); |
| 1687 | } | 1687 | } |
| 1688 | 1688 | ||
| 1689 | if (self.base.options.z_nocopyreloc) { | 1689 | if (self.z_nocopyreloc) { |
| 1690 | try argv.append("-z"); | 1690 | try argv.append("-z"); |
| 1691 | try argv.append("nocopyreloc"); | 1691 | try argv.append("nocopyreloc"); |
| 1692 | } | 1692 | } |
| 1693 | 1693 | ||
| 1694 | if (self.base.options.z_now) { | 1694 | if (self.z_now) { |
| 1695 | try argv.append("-z"); | 1695 | try argv.append("-z"); |
| 1696 | try argv.append("now"); | 1696 | try argv.append("now"); |
| 1697 | } | 1697 | } |
| ... | @@ -1702,11 +1702,11 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1702,11 +1702,11 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1702 | try argv.append("-shared"); | 1702 | try argv.append("-shared"); |
| 1703 | } | 1703 | } |
| 1704 | 1704 | ||
| 1705 | if (self.base.options.pie and self.base.isExe()) { | 1705 | if (comp.config.pie and self.base.isExe()) { |
| 1706 | try argv.append("-pie"); | 1706 | try argv.append("-pie"); |
| 1707 | } | 1707 | } |
| 1708 | 1708 | ||
| 1709 | if (self.base.options.strip) { | 1709 | if (self.base.debug_format == .strip) { |
| 1710 | try argv.append("-s"); | 1710 | try argv.append("-s"); |
| 1711 | } | 1711 | } |
| 1712 | 1712 | ||
| ... | @@ -1715,12 +1715,12 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1715,12 +1715,12 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1715 | if (csu.crti) |v| try argv.append(v); | 1715 | if (csu.crti) |v| try argv.append(v); |
| 1716 | if (csu.crtbegin) |v| try argv.append(v); | 1716 | if (csu.crtbegin) |v| try argv.append(v); |
| 1717 | 1717 | ||
| 1718 | for (self.base.options.lib_dirs) |lib_dir| { | 1718 | for (self.lib_dirs) |lib_dir| { |
| 1719 | try argv.append("-L"); | 1719 | try argv.append("-L"); |
| 1720 | try argv.append(lib_dir); | 1720 | try argv.append(lib_dir); |
| 1721 | } | 1721 | } |
| 1722 | 1722 | ||
| 1723 | if (self.base.options.link_libc) { | 1723 | if (comp.config.link_libc) { |
| 1724 | if (self.base.comp.libc_installation) |libc_installation| { | 1724 | if (self.base.comp.libc_installation) |libc_installation| { |
| 1725 | try argv.append("-L"); | 1725 | try argv.append("-L"); |
| 1726 | try argv.append(libc_installation.crt_dir.?); | 1726 | try argv.append(libc_installation.crt_dir.?); |
| ... | @@ -1728,7 +1728,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1728,7 +1728,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1728 | } | 1728 | } |
| 1729 | 1729 | ||
| 1730 | var whole_archive = false; | 1730 | var whole_archive = false; |
| 1731 | for (self.base.options.objects) |obj| { | 1731 | for (comp.objects) |obj| { |
| 1732 | if (obj.must_link and !whole_archive) { | 1732 | if (obj.must_link and !whole_archive) { |
| 1733 | try argv.append("-whole-archive"); | 1733 | try argv.append("-whole-archive"); |
| 1734 | whole_archive = true; | 1734 | whole_archive = true; |
| ... | @@ -1756,15 +1756,12 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1756,15 +1756,12 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1756 | try argv.append(p); | 1756 | try argv.append(p); |
| 1757 | } | 1757 | } |
| 1758 | 1758 | ||
| 1759 | // TSAN | 1759 | if (comp.config.any_sanitize_thread) { |
| 1760 | if (self.base.options.tsan) { | ||
| 1761 | try argv.append(comp.tsan_static_lib.?.full_object_path); | 1760 | try argv.append(comp.tsan_static_lib.?.full_object_path); |
| 1762 | } | 1761 | } |
| 1763 | 1762 | ||
| 1764 | // libc | 1763 | // libc |
| 1765 | if (!self.base.options.skip_linker_dependencies and | 1764 | if (!comp.skip_linker_dependencies and !comp.config.link_libc) { |
| 1766 | !self.base.options.link_libc) | ||
| 1767 | { | ||
| 1768 | if (comp.libc_static_lib) |lib| { | 1765 | if (comp.libc_static_lib) |lib| { |
| 1769 | try argv.append(lib.full_object_path); | 1766 | try argv.append(lib.full_object_path); |
| 1770 | } | 1767 | } |
| ... | @@ -1799,18 +1796,18 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1799,18 +1796,18 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1799 | } | 1796 | } |
| 1800 | 1797 | ||
| 1801 | // libc++ dep | 1798 | // libc++ dep |
| 1802 | if (self.base.options.link_libcpp) { | 1799 | if (comp.config.link_libcpp) { |
| 1803 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); | 1800 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 1804 | try argv.append(comp.libcxx_static_lib.?.full_object_path); | 1801 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 1805 | } | 1802 | } |
| 1806 | 1803 | ||
| 1807 | // libunwind dep | 1804 | // libunwind dep |
| 1808 | if (self.base.options.link_libunwind) { | 1805 | if (comp.config.link_libunwind) { |
| 1809 | try argv.append(comp.libunwind_static_lib.?.full_object_path); | 1806 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 1810 | } | 1807 | } |
| 1811 | 1808 | ||
| 1812 | // libc dep | 1809 | // libc dep |
| 1813 | if (self.base.options.link_libc) { | 1810 | if (comp.config.link_libc) { |
| 1814 | if (self.base.comp.libc_installation != null) { | 1811 | if (self.base.comp.libc_installation != null) { |
| 1815 | const needs_grouping = link_mode == .Static; | 1812 | const needs_grouping = link_mode == .Static; |
| 1816 | if (needs_grouping) try argv.append("--start-group"); | 1813 | if (needs_grouping) try argv.append("--start-group"); |
| ... | @@ -1963,8 +1960,6 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { | ... | @@ -1963,8 +1960,6 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1963 | defer script.deinit(gpa); | 1960 | defer script.deinit(gpa); |
| 1964 | try script.parse(data, self); | 1961 | try script.parse(data, self); |
| 1965 | 1962 | ||
| 1966 | const lib_dirs = self.base.options.lib_dirs; | ||
| 1967 | |||
| 1968 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); | 1963 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| 1969 | defer arena_allocator.deinit(); | 1964 | defer arena_allocator.deinit(); |
| 1970 | const arena = arena_allocator.allocator(); | 1965 | const arena = arena_allocator.allocator(); |
| ... | @@ -1981,7 +1976,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { | ... | @@ -1981,7 +1976,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1981 | 1976 | ||
| 1982 | // TODO I think technically we should re-use the mechanism used by the frontend here. | 1977 | // TODO I think technically we should re-use the mechanism used by the frontend here. |
| 1983 | // Maybe we should hoist search-strategy all the way here? | 1978 | // Maybe we should hoist search-strategy all the way here? |
| 1984 | for (lib_dirs) |lib_dir| { | 1979 | for (self.lib_dirs) |lib_dir| { |
| 1985 | if (!self.isStatic()) { | 1980 | if (!self.isStatic()) { |
| 1986 | if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Dynamic)) | 1981 | if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Dynamic)) |
| 1987 | break :success; | 1982 | break :success; |
| ... | @@ -1998,7 +1993,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { | ... | @@ -1998,7 +1993,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1998 | } else |_| {} | 1993 | } else |_| {} |
| 1999 | 1994 | ||
| 2000 | try checked_paths.append(try gpa.dupe(u8, scr_obj.path)); | 1995 | try checked_paths.append(try gpa.dupe(u8, scr_obj.path)); |
| 2001 | for (lib_dirs) |lib_dir| { | 1996 | for (self.lib_dirs) |lib_dir| { |
| 2002 | if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, scr_obj.path, null)) | 1997 | if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, scr_obj.path, null)) |
| 2003 | break :success; | 1998 | break :success; |
| 2004 | } | 1999 | } |
| ... | @@ -2338,7 +2333,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2338,7 +2333,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2338 | const link_mode = self.base.comp.config.link_mode; | 2333 | const link_mode = self.base.comp.config.link_mode; |
| 2339 | const is_dyn_lib = link_mode == .Dynamic and is_lib; | 2334 | const is_dyn_lib = link_mode == .Dynamic and is_lib; |
| 2340 | const is_exe_or_dyn_lib = is_dyn_lib or output_mode == .Exe; | 2335 | const is_exe_or_dyn_lib = is_dyn_lib or output_mode == .Exe; |
| 2341 | const have_dynamic_linker = self.base.options.link_libc and | 2336 | const have_dynamic_linker = comp.config.link_libc and |
| 2342 | link_mode == .Dynamic and is_exe_or_dyn_lib; | 2337 | link_mode == .Dynamic and is_exe_or_dyn_lib; |
| 2343 | const target = self.base.comp.root_mod.resolved_target.result; | 2338 | const target = self.base.comp.root_mod.resolved_target.result; |
| 2344 | const compiler_rt_path: ?[]const u8 = blk: { | 2339 | const compiler_rt_path: ?[]const u8 = blk: { |
| ... | @@ -2358,11 +2353,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2358,11 +2353,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2358 | const id_symlink_basename = "lld.id"; | 2353 | const id_symlink_basename = "lld.id"; |
| 2359 | 2354 | ||
| 2360 | var man: Cache.Manifest = undefined; | 2355 | var man: Cache.Manifest = undefined; |
| 2361 | defer if (!self.base.options.disable_lld_caching) man.deinit(); | 2356 | defer if (!self.base.disable_lld_caching) man.deinit(); |
| 2362 | 2357 | ||
| 2363 | var digest: [Cache.hex_digest_len]u8 = undefined; | 2358 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 2364 | 2359 | ||
| 2365 | if (!self.base.options.disable_lld_caching) { | 2360 | if (!self.base.disable_lld_caching) { |
| 2366 | man = comp.cache_parent.obtain(); | 2361 | man = comp.cache_parent.obtain(); |
| 2367 | 2362 | ||
| 2368 | // We are about to obtain this lock, so here we give other processes a chance first. | 2363 | // We are about to obtain this lock, so here we give other processes a chance first. |
| ... | @@ -2370,9 +2365,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2370,9 +2365,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2370 | 2365 | ||
| 2371 | comptime assert(Compilation.link_hash_implementation_version == 10); | 2366 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 2372 | 2367 | ||
| 2373 | try man.addOptionalFile(self.base.options.linker_script); | 2368 | try man.addOptionalFile(self.linker_script); |
| 2374 | try man.addOptionalFile(self.base.options.version_script); | 2369 | try man.addOptionalFile(self.version_script); |
| 2375 | for (self.base.options.objects) |obj| { | 2370 | for (comp.objects) |obj| { |
| 2376 | _ = try man.addFile(obj.path, null); | 2371 | _ = try man.addFile(obj.path, null); |
| 2377 | man.hash.add(obj.must_link); | 2372 | man.hash.add(obj.must_link); |
| 2378 | man.hash.add(obj.loption); | 2373 | man.hash.add(obj.loption); |
| ... | @@ -2385,34 +2380,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2385,34 +2380,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2385 | 2380 | ||
| 2386 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig | 2381 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig |
| 2387 | // installation sources because they are always a product of the compiler version + target information. | 2382 | // installation sources because they are always a product of the compiler version + target information. |
| 2388 | man.hash.addOptionalBytes(self.base.options.entry); | 2383 | man.hash.addOptionalBytes(comp.config.entry); |
| 2389 | man.hash.addOptional(self.image_base); | 2384 | man.hash.addOptional(self.image_base); |
| 2390 | man.hash.add(self.base.gc_sections); | 2385 | man.hash.add(self.base.gc_sections); |
| 2391 | man.hash.addOptional(self.base.options.sort_section); | 2386 | man.hash.addOptional(self.sort_section); |
| 2392 | man.hash.add(self.base.options.eh_frame_hdr); | 2387 | man.hash.add(self.eh_frame_hdr); |
| 2393 | man.hash.add(self.base.options.emit_relocs); | 2388 | man.hash.add(self.emit_relocs); |
| 2394 | man.hash.add(self.base.options.rdynamic); | 2389 | man.hash.add(self.rdynamic); |
| 2395 | man.hash.addListOfBytes(self.base.options.lib_dirs); | 2390 | man.hash.addListOfBytes(self.lib_dirs); |
| 2396 | man.hash.addListOfBytes(self.base.options.rpath_list); | 2391 | man.hash.addListOfBytes(self.base.rpath_list); |
| 2397 | man.hash.add(self.base.options.each_lib_rpath); | 2392 | man.hash.add(self.each_lib_rpath); |
| 2398 | if (output_mode == .Exe) { | 2393 | if (output_mode == .Exe) { |
| 2399 | man.hash.add(self.base.stack_size); | 2394 | man.hash.add(self.base.stack_size); |
| 2400 | man.hash.add(self.base.build_id); | 2395 | man.hash.add(self.base.build_id); |
| 2401 | } | 2396 | } |
| 2402 | man.hash.addListOfBytes(self.base.options.symbol_wrap_set.keys()); | 2397 | man.hash.addListOfBytes(self.symbol_wrap_set.keys()); |
| 2403 | man.hash.add(self.base.options.skip_linker_dependencies); | 2398 | man.hash.add(comp.skip_linker_dependencies); |
| 2404 | man.hash.add(self.base.options.z_nodelete); | 2399 | man.hash.add(self.z_nodelete); |
| 2405 | man.hash.add(self.base.options.z_notext); | 2400 | man.hash.add(self.z_notext); |
| 2406 | man.hash.add(self.base.options.z_defs); | 2401 | man.hash.add(self.z_defs); |
| 2407 | man.hash.add(self.base.options.z_origin); | 2402 | man.hash.add(self.z_origin); |
| 2408 | man.hash.add(self.base.options.z_nocopyreloc); | 2403 | man.hash.add(self.z_nocopyreloc); |
| 2409 | man.hash.add(self.base.options.z_now); | 2404 | man.hash.add(self.z_now); |
| 2410 | man.hash.add(self.base.options.z_relro); | 2405 | man.hash.add(self.z_relro); |
| 2411 | man.hash.add(self.base.options.z_common_page_size orelse 0); | 2406 | man.hash.add(self.z_common_page_size orelse 0); |
| 2412 | man.hash.add(self.base.options.z_max_page_size orelse 0); | 2407 | man.hash.add(self.z_max_page_size orelse 0); |
| 2413 | man.hash.add(self.base.options.hash_style); | 2408 | man.hash.add(self.hash_style); |
| 2414 | // strip does not need to go into the linker hash because it is part of the hash namespace | 2409 | // strip does not need to go into the linker hash because it is part of the hash namespace |
| 2415 | if (self.base.options.link_libc) { | 2410 | if (comp.config.link_libc) { |
| 2416 | man.hash.add(self.base.comp.libc_installation != null); | 2411 | man.hash.add(self.base.comp.libc_installation != null); |
| 2417 | if (self.base.comp.libc_installation) |libc_installation| { | 2412 | if (self.base.comp.libc_installation) |libc_installation| { |
| 2418 | man.hash.addBytes(libc_installation.crt_dir.?); | 2413 | man.hash.addBytes(libc_installation.crt_dir.?); |
| ... | @@ -2421,16 +2416,16 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2421,16 +2416,16 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2421 | man.hash.addOptionalBytes(target.dynamic_linker.get()); | 2416 | man.hash.addOptionalBytes(target.dynamic_linker.get()); |
| 2422 | } | 2417 | } |
| 2423 | } | 2418 | } |
| 2424 | man.hash.addOptionalBytes(self.base.options.soname); | 2419 | man.hash.addOptionalBytes(self.soname); |
| 2425 | man.hash.addOptional(self.base.options.version); | 2420 | man.hash.addOptional(comp.version); |
| 2426 | try link.hashAddSystemLibs(&man, self.base.comp.system_libs); | 2421 | try link.hashAddSystemLibs(&man, self.base.comp.system_libs); |
| 2427 | man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys()); | 2422 | man.hash.addListOfBytes(self.base.force_undefined_symbols.keys()); |
| 2428 | man.hash.add(self.base.allow_shlib_undefined); | 2423 | man.hash.add(self.base.allow_shlib_undefined); |
| 2429 | man.hash.add(self.base.options.bind_global_refs_locally); | 2424 | man.hash.add(self.bind_global_refs_locally); |
| 2430 | man.hash.add(self.base.options.compress_debug_sections); | 2425 | man.hash.add(self.compress_debug_sections); |
| 2431 | man.hash.add(self.base.options.tsan); | 2426 | man.hash.add(comp.config.any_sanitize_thread); |
| 2432 | man.hash.addOptionalBytes(self.base.options.sysroot); | 2427 | man.hash.addOptionalBytes(self.sysroot); |
| 2433 | man.hash.add(self.base.options.linker_optimization); | 2428 | man.hash.add(self.optimization); |
| 2434 | 2429 | ||
| 2435 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. | 2430 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 2436 | _ = try man.hit(); | 2431 | _ = try man.hit(); |
| ... | @@ -2466,14 +2461,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2466,14 +2461,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2466 | // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails | 2461 | // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails |
| 2467 | // before even generating the relocatable. | 2462 | // before even generating the relocatable. |
| 2468 | if (output_mode == .Obj and | 2463 | if (output_mode == .Obj and |
| 2469 | (self.base.options.lto or target.isBpfFreestanding())) | 2464 | (comp.config.lto or target.isBpfFreestanding())) |
| 2470 | { | 2465 | { |
| 2471 | // In this case we must do a simple file copy | 2466 | // In this case we must do a simple file copy |
| 2472 | // here. TODO: think carefully about how we can avoid this redundant operation when doing | 2467 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 2473 | // build-obj. See also the corresponding TODO in linkAsArchive. | 2468 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 2474 | const the_object_path = blk: { | 2469 | const the_object_path = blk: { |
| 2475 | if (self.base.options.objects.len != 0) | 2470 | if (comp.objects.len != 0) |
| 2476 | break :blk self.base.options.objects[0].path; | 2471 | break :blk comp.objects[0].path; |
| 2477 | 2472 | ||
| 2478 | if (comp.c_object_table.count() != 0) | 2473 | if (comp.c_object_table.count() != 0) |
| 2479 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 2474 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -2505,32 +2500,32 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2505,32 +2500,32 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2505 | 2500 | ||
| 2506 | try argv.append("--error-limit=0"); | 2501 | try argv.append("--error-limit=0"); |
| 2507 | 2502 | ||
| 2508 | if (self.base.options.sysroot) |sysroot| { | 2503 | if (self.sysroot) |sysroot| { |
| 2509 | try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot})); | 2504 | try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot})); |
| 2510 | } | 2505 | } |
| 2511 | 2506 | ||
| 2512 | if (self.base.options.lto) { | 2507 | if (comp.config.lto) { |
| 2513 | switch (self.base.options.optimize_mode) { | 2508 | switch (comp.root_mod.optimize_mode) { |
| 2514 | .Debug => {}, | 2509 | .Debug => {}, |
| 2515 | .ReleaseSmall => try argv.append("--lto-O2"), | 2510 | .ReleaseSmall => try argv.append("--lto-O2"), |
| 2516 | .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"), | 2511 | .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"), |
| 2517 | } | 2512 | } |
| 2518 | } | 2513 | } |
| 2519 | try argv.append(try std.fmt.allocPrint(arena, "-O{d}", .{ | 2514 | try argv.append(try std.fmt.allocPrint(arena, "-O{d}", .{ |
| 2520 | self.base.options.linker_optimization, | 2515 | self.optimization, |
| 2521 | })); | 2516 | })); |
| 2522 | 2517 | ||
| 2523 | if (self.base.options.entry) |entry| { | 2518 | if (comp.config.entry) |entry| { |
| 2524 | try argv.append("--entry"); | 2519 | try argv.append("--entry"); |
| 2525 | try argv.append(entry); | 2520 | try argv.append(entry); |
| 2526 | } | 2521 | } |
| 2527 | 2522 | ||
| 2528 | for (self.base.options.force_undefined_symbols.keys()) |sym| { | 2523 | for (self.base.force_undefined_symbols.keys()) |sym| { |
| 2529 | try argv.append("-u"); | 2524 | try argv.append("-u"); |
| 2530 | try argv.append(sym); | 2525 | try argv.append(sym); |
| 2531 | } | 2526 | } |
| 2532 | 2527 | ||
| 2533 | switch (self.base.options.hash_style) { | 2528 | switch (self.hash_style) { |
| 2534 | .gnu => try argv.append("--hash-style=gnu"), | 2529 | .gnu => try argv.append("--hash-style=gnu"), |
| 2535 | .sysv => try argv.append("--hash-style=sysv"), | 2530 | .sysv => try argv.append("--hash-style=sysv"), |
| 2536 | .both => {}, // this is the default | 2531 | .both => {}, // this is the default |
| ... | @@ -2559,12 +2554,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2559,12 +2554,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2559 | 2554 | ||
| 2560 | try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base})); | 2555 | try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base})); |
| 2561 | 2556 | ||
| 2562 | if (self.base.options.linker_script) |linker_script| { | 2557 | if (self.linker_script) |linker_script| { |
| 2563 | try argv.append("-T"); | 2558 | try argv.append("-T"); |
| 2564 | try argv.append(linker_script); | 2559 | try argv.append(linker_script); |
| 2565 | } | 2560 | } |
| 2566 | 2561 | ||
| 2567 | if (self.base.options.sort_section) |how| { | 2562 | if (self.sort_section) |how| { |
| 2568 | const arg = try std.fmt.allocPrint(arena, "--sort-section={s}", .{@tagName(how)}); | 2563 | const arg = try std.fmt.allocPrint(arena, "--sort-section={s}", .{@tagName(how)}); |
| 2569 | try argv.append(arg); | 2564 | try argv.append(arg); |
| 2570 | } | 2565 | } |
| ... | @@ -2573,67 +2568,67 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2573,67 +2568,67 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2573 | try argv.append("--gc-sections"); | 2568 | try argv.append("--gc-sections"); |
| 2574 | } | 2569 | } |
| 2575 | 2570 | ||
| 2576 | if (self.base.options.print_gc_sections) { | 2571 | if (self.base.print_gc_sections) { |
| 2577 | try argv.append("--print-gc-sections"); | 2572 | try argv.append("--print-gc-sections"); |
| 2578 | } | 2573 | } |
| 2579 | 2574 | ||
| 2580 | if (self.base.options.print_icf_sections) { | 2575 | if (self.print_icf_sections) { |
| 2581 | try argv.append("--print-icf-sections"); | 2576 | try argv.append("--print-icf-sections"); |
| 2582 | } | 2577 | } |
| 2583 | 2578 | ||
| 2584 | if (self.base.options.print_map) { | 2579 | if (self.print_map) { |
| 2585 | try argv.append("--print-map"); | 2580 | try argv.append("--print-map"); |
| 2586 | } | 2581 | } |
| 2587 | 2582 | ||
| 2588 | if (self.base.options.eh_frame_hdr) { | 2583 | if (self.eh_frame_hdr) { |
| 2589 | try argv.append("--eh-frame-hdr"); | 2584 | try argv.append("--eh-frame-hdr"); |
| 2590 | } | 2585 | } |
| 2591 | 2586 | ||
| 2592 | if (self.base.options.emit_relocs) { | 2587 | if (self.emit_relocs) { |
| 2593 | try argv.append("--emit-relocs"); | 2588 | try argv.append("--emit-relocs"); |
| 2594 | } | 2589 | } |
| 2595 | 2590 | ||
| 2596 | if (self.base.options.rdynamic) { | 2591 | if (self.rdynamic) { |
| 2597 | try argv.append("--export-dynamic"); | 2592 | try argv.append("--export-dynamic"); |
| 2598 | } | 2593 | } |
| 2599 | 2594 | ||
| 2600 | if (self.base.options.strip) { | 2595 | if (self.base.debug_format == .strip) { |
| 2601 | try argv.append("-s"); | 2596 | try argv.append("-s"); |
| 2602 | } | 2597 | } |
| 2603 | 2598 | ||
| 2604 | if (self.base.options.z_nodelete) { | 2599 | if (self.z_nodelete) { |
| 2605 | try argv.append("-z"); | 2600 | try argv.append("-z"); |
| 2606 | try argv.append("nodelete"); | 2601 | try argv.append("nodelete"); |
| 2607 | } | 2602 | } |
| 2608 | if (self.base.options.z_notext) { | 2603 | if (self.z_notext) { |
| 2609 | try argv.append("-z"); | 2604 | try argv.append("-z"); |
| 2610 | try argv.append("notext"); | 2605 | try argv.append("notext"); |
| 2611 | } | 2606 | } |
| 2612 | if (self.base.options.z_defs) { | 2607 | if (self.z_defs) { |
| 2613 | try argv.append("-z"); | 2608 | try argv.append("-z"); |
| 2614 | try argv.append("defs"); | 2609 | try argv.append("defs"); |
| 2615 | } | 2610 | } |
| 2616 | if (self.base.options.z_origin) { | 2611 | if (self.z_origin) { |
| 2617 | try argv.append("-z"); | 2612 | try argv.append("-z"); |
| 2618 | try argv.append("origin"); | 2613 | try argv.append("origin"); |
| 2619 | } | 2614 | } |
| 2620 | if (self.base.options.z_nocopyreloc) { | 2615 | if (self.z_nocopyreloc) { |
| 2621 | try argv.append("-z"); | 2616 | try argv.append("-z"); |
| 2622 | try argv.append("nocopyreloc"); | 2617 | try argv.append("nocopyreloc"); |
| 2623 | } | 2618 | } |
| 2624 | if (self.base.options.z_now) { | 2619 | if (self.z_now) { |
| 2625 | // LLD defaults to -zlazy | 2620 | // LLD defaults to -zlazy |
| 2626 | try argv.append("-znow"); | 2621 | try argv.append("-znow"); |
| 2627 | } | 2622 | } |
| 2628 | if (!self.base.options.z_relro) { | 2623 | if (!self.z_relro) { |
| 2629 | // LLD defaults to -zrelro | 2624 | // LLD defaults to -zrelro |
| 2630 | try argv.append("-znorelro"); | 2625 | try argv.append("-znorelro"); |
| 2631 | } | 2626 | } |
| 2632 | if (self.base.options.z_common_page_size) |size| { | 2627 | if (self.z_common_page_size) |size| { |
| 2633 | try argv.append("-z"); | 2628 | try argv.append("-z"); |
| 2634 | try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size})); | 2629 | try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size})); |
| 2635 | } | 2630 | } |
| 2636 | if (self.base.options.z_max_page_size) |size| { | 2631 | if (self.z_max_page_size) |size| { |
| 2637 | try argv.append("-z"); | 2632 | try argv.append("-z"); |
| 2638 | try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size})); | 2633 | try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size})); |
| 2639 | } | 2634 | } |
| ... | @@ -2658,7 +2653,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2658,7 +2653,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2658 | try argv.append("-shared"); | 2653 | try argv.append("-shared"); |
| 2659 | } | 2654 | } |
| 2660 | 2655 | ||
| 2661 | if (self.base.options.pie and output_mode == .Exe) { | 2656 | if (comp.config.pie and output_mode == .Exe) { |
| 2662 | try argv.append("-pie"); | 2657 | try argv.append("-pie"); |
| 2663 | } | 2658 | } |
| 2664 | 2659 | ||
| ... | @@ -2683,20 +2678,20 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2683,20 +2678,20 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2683 | // rpaths | 2678 | // rpaths |
| 2684 | var rpath_table = std.StringHashMap(void).init(gpa); | 2679 | var rpath_table = std.StringHashMap(void).init(gpa); |
| 2685 | defer rpath_table.deinit(); | 2680 | defer rpath_table.deinit(); |
| 2686 | for (self.base.options.rpath_list) |rpath| { | 2681 | for (self.base.rpath_list) |rpath| { |
| 2687 | if ((try rpath_table.fetchPut(rpath, {})) == null) { | 2682 | if ((try rpath_table.fetchPut(rpath, {})) == null) { |
| 2688 | try argv.append("-rpath"); | 2683 | try argv.append("-rpath"); |
| 2689 | try argv.append(rpath); | 2684 | try argv.append(rpath); |
| 2690 | } | 2685 | } |
| 2691 | } | 2686 | } |
| 2692 | 2687 | ||
| 2693 | for (self.base.options.symbol_wrap_set.keys()) |symbol_name| { | 2688 | for (self.symbol_wrap_set.keys()) |symbol_name| { |
| 2694 | try argv.appendSlice(&.{ "-wrap", symbol_name }); | 2689 | try argv.appendSlice(&.{ "-wrap", symbol_name }); |
| 2695 | } | 2690 | } |
| 2696 | 2691 | ||
| 2697 | if (self.base.options.each_lib_rpath) { | 2692 | if (self.each_lib_rpath) { |
| 2698 | var test_path = std.ArrayList(u8).init(arena); | 2693 | var test_path = std.ArrayList(u8).init(arena); |
| 2699 | for (self.base.options.lib_dirs) |lib_dir_path| { | 2694 | for (self.lib_dirs) |lib_dir_path| { |
| 2700 | for (self.base.comp.system_libs.keys()) |link_lib| { | 2695 | for (self.base.comp.system_libs.keys()) |link_lib| { |
| 2701 | if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic))) | 2696 | if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic))) |
| 2702 | continue; | 2697 | continue; |
| ... | @@ -2706,7 +2701,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2706,7 +2701,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2706 | } | 2701 | } |
| 2707 | } | 2702 | } |
| 2708 | } | 2703 | } |
| 2709 | for (self.base.options.objects) |obj| { | 2704 | for (comp.objects) |obj| { |
| 2710 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { | 2705 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| 2711 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; | 2706 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| 2712 | if (obj.loption) continue; | 2707 | if (obj.loption) continue; |
| ... | @@ -2719,12 +2714,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2719,12 +2714,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2719 | } | 2714 | } |
| 2720 | } | 2715 | } |
| 2721 | 2716 | ||
| 2722 | for (self.base.options.lib_dirs) |lib_dir| { | 2717 | for (self.lib_dirs) |lib_dir| { |
| 2723 | try argv.append("-L"); | 2718 | try argv.append("-L"); |
| 2724 | try argv.append(lib_dir); | 2719 | try argv.append(lib_dir); |
| 2725 | } | 2720 | } |
| 2726 | 2721 | ||
| 2727 | if (self.base.options.link_libc) { | 2722 | if (comp.config.link_libc) { |
| 2728 | if (self.base.comp.libc_installation) |libc_installation| { | 2723 | if (self.base.comp.libc_installation) |libc_installation| { |
| 2729 | try argv.append("-L"); | 2724 | try argv.append("-L"); |
| 2730 | try argv.append(libc_installation.crt_dir.?); | 2725 | try argv.append(libc_installation.crt_dir.?); |
| ... | @@ -2739,11 +2734,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2739,11 +2734,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2739 | } | 2734 | } |
| 2740 | 2735 | ||
| 2741 | if (is_dyn_lib) { | 2736 | if (is_dyn_lib) { |
| 2742 | if (self.base.options.soname) |soname| { | 2737 | if (self.soname) |soname| { |
| 2743 | try argv.append("-soname"); | 2738 | try argv.append("-soname"); |
| 2744 | try argv.append(soname); | 2739 | try argv.append(soname); |
| 2745 | } | 2740 | } |
| 2746 | if (self.base.options.version_script) |version_script| { | 2741 | if (self.version_script) |version_script| { |
| 2747 | try argv.append("-version-script"); | 2742 | try argv.append("-version-script"); |
| 2748 | try argv.append(version_script); | 2743 | try argv.append(version_script); |
| 2749 | } | 2744 | } |
| ... | @@ -2751,7 +2746,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2751,7 +2746,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2751 | 2746 | ||
| 2752 | // Positional arguments to the linker such as object files. | 2747 | // Positional arguments to the linker such as object files. |
| 2753 | var whole_archive = false; | 2748 | var whole_archive = false; |
| 2754 | for (self.base.options.objects) |obj| { | 2749 | for (comp.objects) |obj| { |
| 2755 | if (obj.must_link and !whole_archive) { | 2750 | if (obj.must_link and !whole_archive) { |
| 2756 | try argv.append("-whole-archive"); | 2751 | try argv.append("-whole-archive"); |
| 2757 | whole_archive = true; | 2752 | whole_archive = true; |
| ... | @@ -2779,15 +2774,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2779,15 +2774,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2779 | try argv.append(p); | 2774 | try argv.append(p); |
| 2780 | } | 2775 | } |
| 2781 | 2776 | ||
| 2782 | // TSAN | 2777 | if (comp.config.any_sanitize_thread) { |
| 2783 | if (self.base.options.tsan) { | ||
| 2784 | try argv.append(comp.tsan_static_lib.?.full_object_path); | 2778 | try argv.append(comp.tsan_static_lib.?.full_object_path); |
| 2785 | } | 2779 | } |
| 2786 | 2780 | ||
| 2787 | // libc | 2781 | // libc |
| 2788 | if (is_exe_or_dyn_lib and | 2782 | if (is_exe_or_dyn_lib and |
| 2789 | !self.base.options.skip_linker_dependencies and | 2783 | !comp.skip_linker_dependencies and |
| 2790 | !self.base.options.link_libc) | 2784 | !comp.config.link_libc) |
| 2791 | { | 2785 | { |
| 2792 | if (comp.libc_static_lib) |lib| { | 2786 | if (comp.libc_static_lib) |lib| { |
| 2793 | try argv.append(lib.full_object_path); | 2787 | try argv.append(lib.full_object_path); |
| ... | @@ -2832,19 +2826,19 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2832,19 +2826,19 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2832 | } | 2826 | } |
| 2833 | 2827 | ||
| 2834 | // libc++ dep | 2828 | // libc++ dep |
| 2835 | if (self.base.options.link_libcpp) { | 2829 | if (comp.config.link_libcpp) { |
| 2836 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); | 2830 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 2837 | try argv.append(comp.libcxx_static_lib.?.full_object_path); | 2831 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 2838 | } | 2832 | } |
| 2839 | 2833 | ||
| 2840 | // libunwind dep | 2834 | // libunwind dep |
| 2841 | if (self.base.options.link_libunwind) { | 2835 | if (comp.config.link_libunwind) { |
| 2842 | try argv.append(comp.libunwind_static_lib.?.full_object_path); | 2836 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 2843 | } | 2837 | } |
| 2844 | 2838 | ||
| 2845 | // libc dep | 2839 | // libc dep |
| 2846 | self.error_flags.missing_libc = false; | 2840 | self.error_flags.missing_libc = false; |
| 2847 | if (self.base.options.link_libc) { | 2841 | if (comp.config.link_libc) { |
| 2848 | if (self.base.comp.libc_installation != null) { | 2842 | if (self.base.comp.libc_installation != null) { |
| 2849 | const needs_grouping = link_mode == .Static; | 2843 | const needs_grouping = link_mode == .Static; |
| 2850 | if (needs_grouping) try argv.append("--start-group"); | 2844 | if (needs_grouping) try argv.append("--start-group"); |
| ... | @@ -2884,13 +2878,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2884,13 +2878,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2884 | try argv.append("--allow-shlib-undefined"); | 2878 | try argv.append("--allow-shlib-undefined"); |
| 2885 | } | 2879 | } |
| 2886 | 2880 | ||
| 2887 | switch (self.base.options.compress_debug_sections) { | 2881 | switch (self.compress_debug_sections) { |
| 2888 | .none => {}, | 2882 | .none => {}, |
| 2889 | .zlib => try argv.append("--compress-debug-sections=zlib"), | 2883 | .zlib => try argv.append("--compress-debug-sections=zlib"), |
| 2890 | .zstd => try argv.append("--compress-debug-sections=zstd"), | 2884 | .zstd => try argv.append("--compress-debug-sections=zstd"), |
| 2891 | } | 2885 | } |
| 2892 | 2886 | ||
| 2893 | if (self.base.options.bind_global_refs_locally) { | 2887 | if (self.bind_global_refs_locally) { |
| 2894 | try argv.append("-Bsymbolic"); | 2888 | try argv.append("-Bsymbolic"); |
| 2895 | } | 2889 | } |
| 2896 | 2890 | ||
| ... | @@ -2964,7 +2958,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2964,7 +2958,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2964 | } | 2958 | } |
| 2965 | } | 2959 | } |
| 2966 | 2960 | ||
| 2967 | if (!self.base.options.disable_lld_caching) { | 2961 | if (!self.base.disable_lld_caching) { |
| 2968 | // Update the file with the digest. If it fails we can continue; it only | 2962 | // Update the file with the digest. If it fails we can continue; it only |
| 2969 | // means that the next invocation will have an unnecessary cache miss. | 2963 | // means that the next invocation will have an unnecessary cache miss. |
| 2970 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { | 2964 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { |
| ... | @@ -3101,7 +3095,8 @@ fn writeElfHeader(self: *Elf) !void { | ... | @@ -3101,7 +3095,8 @@ fn writeElfHeader(self: *Elf) !void { |
| 3101 | }; | 3095 | }; |
| 3102 | index += 1; | 3096 | index += 1; |
| 3103 | 3097 | ||
| 3104 | const target = self.base.comp.root_mod.resolved_target.result; | 3098 | const comp = self.base.comp; |
| 3099 | const target = comp.root_mod.resolved_target.result; | ||
| 3105 | const endian = target.cpu.arch.endian(); | 3100 | const endian = target.cpu.arch.endian(); |
| 3106 | hdr_buf[index] = switch (endian) { | 3101 | hdr_buf[index] = switch (endian) { |
| 3107 | .little => elf.ELFDATA2LSB, | 3102 | .little => elf.ELFDATA2LSB, |
| ... | @@ -3120,10 +3115,10 @@ fn writeElfHeader(self: *Elf) !void { | ... | @@ -3120,10 +3115,10 @@ fn writeElfHeader(self: *Elf) !void { |
| 3120 | 3115 | ||
| 3121 | assert(index == 16); | 3116 | assert(index == 16); |
| 3122 | 3117 | ||
| 3123 | const output_mode = self.base.comp.config.output_mode; | 3118 | const output_mode = comp.config.output_mode; |
| 3124 | const link_mode = self.base.comp.config.link_mode; | 3119 | const link_mode = comp.config.link_mode; |
| 3125 | const elf_type: elf.ET = switch (output_mode) { | 3120 | const elf_type: elf.ET = switch (output_mode) { |
| 3126 | .Exe => if (self.base.options.pie) .DYN else .EXEC, | 3121 | .Exe => if (comp.config.pie) .DYN else .EXEC, |
| 3127 | .Obj => .REL, | 3122 | .Obj => .REL, |
| 3128 | .Lib => switch (link_mode) { | 3123 | .Lib => switch (link_mode) { |
| 3129 | .Static => @as(elf.ET, .REL), | 3124 | .Static => @as(elf.ET, .REL), |
| ... | @@ -3283,7 +3278,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { | ... | @@ -3283,7 +3278,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3283 | self.plt_index = try linker_defined.addGlobal("_PROCEDURE_LINKAGE_TABLE_", self); | 3278 | self.plt_index = try linker_defined.addGlobal("_PROCEDURE_LINKAGE_TABLE_", self); |
| 3284 | self.end_index = try linker_defined.addGlobal("_end", self); | 3279 | self.end_index = try linker_defined.addGlobal("_end", self); |
| 3285 | 3280 | ||
| 3286 | if (self.base.options.eh_frame_hdr) { | 3281 | if (self.eh_frame_hdr) { |
| 3287 | self.gnu_eh_frame_hdr_index = try linker_defined.addGlobal("__GNU_EH_FRAME_HDR", self); | 3282 | self.gnu_eh_frame_hdr_index = try linker_defined.addGlobal("__GNU_EH_FRAME_HDR", self); |
| 3288 | } | 3283 | } |
| 3289 | 3284 | ||
| ... | @@ -3314,7 +3309,8 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { | ... | @@ -3314,7 +3309,8 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3314 | } | 3309 | } |
| 3315 | 3310 | ||
| 3316 | fn allocateLinkerDefinedSymbols(self: *Elf) void { | 3311 | fn allocateLinkerDefinedSymbols(self: *Elf) void { |
| 3317 | const link_mode = self.base.comp.config.link_mode; | 3312 | const comp = self.base.comp; |
| 3313 | const link_mode = comp.config.link_mode; | ||
| 3318 | 3314 | ||
| 3319 | // _DYNAMIC | 3315 | // _DYNAMIC |
| 3320 | if (self.dynamic_section_index) |shndx| { | 3316 | if (self.dynamic_section_index) |shndx| { |
| ... | @@ -3398,7 +3394,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void { | ... | @@ -3398,7 +3394,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void { |
| 3398 | 3394 | ||
| 3399 | // __rela_iplt_start, __rela_iplt_end | 3395 | // __rela_iplt_start, __rela_iplt_end |
| 3400 | if (self.rela_dyn_section_index) |shndx| blk: { | 3396 | if (self.rela_dyn_section_index) |shndx| blk: { |
| 3401 | if (link_mode != .Static or self.base.options.pie) break :blk; | 3397 | if (link_mode != .Static or comp.config.pie) break :blk; |
| 3402 | const shdr = &self.shdrs.items[shndx]; | 3398 | const shdr = &self.shdrs.items[shndx]; |
| 3403 | const end_addr = shdr.sh_addr + shdr.sh_size; | 3399 | const end_addr = shdr.sh_addr + shdr.sh_size; |
| 3404 | const start_addr = end_addr - self.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela); | 3400 | const start_addr = end_addr - self.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela); |
| ... | @@ -3445,7 +3441,8 @@ fn initOutputSections(self: *Elf) !void { | ... | @@ -3445,7 +3441,8 @@ fn initOutputSections(self: *Elf) !void { |
| 3445 | } | 3441 | } |
| 3446 | 3442 | ||
| 3447 | fn initSyntheticSections(self: *Elf) !void { | 3443 | fn initSyntheticSections(self: *Elf) !void { |
| 3448 | const target = self.base.comp.root_mod.resolved_target.result; | 3444 | const comp = self.base.comp; |
| 3445 | const target = comp.root_mod.resolved_target.result; | ||
| 3449 | const ptr_size = self.ptrWidthBytes(); | 3446 | const ptr_size = self.ptrWidthBytes(); |
| 3450 | 3447 | ||
| 3451 | const needs_eh_frame = for (self.objects.items) |index| { | 3448 | const needs_eh_frame = for (self.objects.items) |index| { |
| ... | @@ -3460,7 +3457,7 @@ fn initSyntheticSections(self: *Elf) !void { | ... | @@ -3460,7 +3457,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3460 | .offset = std.math.maxInt(u64), | 3457 | .offset = std.math.maxInt(u64), |
| 3461 | }); | 3458 | }); |
| 3462 | 3459 | ||
| 3463 | if (self.base.options.eh_frame_hdr) { | 3460 | if (self.eh_frame_hdr) { |
| 3464 | self.eh_frame_hdr_section_index = try self.addSection(.{ | 3461 | self.eh_frame_hdr_section_index = try self.addSection(.{ |
| 3465 | .name = ".eh_frame_hdr", | 3462 | .name = ".eh_frame_hdr", |
| 3466 | .type = elf.SHT_PROGBITS, | 3463 | .type = elf.SHT_PROGBITS, |
| ... | @@ -3554,7 +3551,7 @@ fn initSyntheticSections(self: *Elf) !void { | ... | @@ -3554,7 +3551,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3554 | // In this case, if we do generate .interp section and segment, we will get | 3551 | // In this case, if we do generate .interp section and segment, we will get |
| 3555 | // a segfault in the dynamic linker trying to load a binary that is static | 3552 | // a segfault in the dynamic linker trying to load a binary that is static |
| 3556 | // and doesn't contain .dynamic section. | 3553 | // and doesn't contain .dynamic section. |
| 3557 | if (self.isStatic() and !self.base.options.pie) break :blk false; | 3554 | if (self.isStatic() and !comp.config.pie) break :blk false; |
| 3558 | break :blk target.dynamic_linker.get() != null; | 3555 | break :blk target.dynamic_linker.get() != null; |
| 3559 | }; | 3556 | }; |
| 3560 | if (needs_interp) { | 3557 | if (needs_interp) { |
| ... | @@ -3567,7 +3564,7 @@ fn initSyntheticSections(self: *Elf) !void { | ... | @@ -3567,7 +3564,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3567 | }); | 3564 | }); |
| 3568 | } | 3565 | } |
| 3569 | 3566 | ||
| 3570 | if (self.base.isDynLib() or self.shared_objects.items.len > 0 or self.base.options.pie) { | 3567 | if (self.base.isDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) { |
| 3571 | self.dynstrtab_section_index = try self.addSection(.{ | 3568 | self.dynstrtab_section_index = try self.addSection(.{ |
| 3572 | .name = ".dynstr", | 3569 | .name = ".dynstr", |
| 3573 | .flags = elf.SHF_ALLOC, | 3570 | .flags = elf.SHF_ALLOC, |
| ... | @@ -3859,7 +3856,7 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void { | ... | @@ -3859,7 +3856,7 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void { |
| 3859 | } | 3856 | } |
| 3860 | 3857 | ||
| 3861 | if (self.base.isDynLib()) { | 3858 | if (self.base.isDynLib()) { |
| 3862 | if (self.base.options.soname) |soname| { | 3859 | if (self.soname) |soname| { |
| 3863 | try self.dynamic.setSoname(soname, self); | 3860 | try self.dynamic.setSoname(soname, self); |
| 3864 | } | 3861 | } |
| 3865 | } | 3862 | } |
src/link/Elf/Atom.zig+7-6| ... | @@ -543,7 +543,7 @@ fn scanReloc( | ... | @@ -543,7 +543,7 @@ fn scanReloc( |
| 543 | try self.reportPicError(symbol, rel, elf_file), | 543 | try self.reportPicError(symbol, rel, elf_file), |
| 544 | 544 | ||
| 545 | .copyrel => { | 545 | .copyrel => { |
| 546 | if (elf_file.base.options.z_nocopyreloc) { | 546 | if (elf_file.z_nocopyreloc) { |
| 547 | if (symbol.isAbs(elf_file)) | 547 | if (symbol.isAbs(elf_file)) |
| 548 | try self.reportNoPicError(symbol, rel, elf_file) | 548 | try self.reportNoPicError(symbol, rel, elf_file) |
| 549 | else | 549 | else |
| ... | @@ -553,9 +553,9 @@ fn scanReloc( | ... | @@ -553,9 +553,9 @@ fn scanReloc( |
| 553 | }, | 553 | }, |
| 554 | 554 | ||
| 555 | .dyn_copyrel => { | 555 | .dyn_copyrel => { |
| 556 | if (is_writeable or elf_file.base.options.z_nocopyreloc) { | 556 | if (is_writeable or elf_file.z_nocopyreloc) { |
| 557 | if (!is_writeable) { | 557 | if (!is_writeable) { |
| 558 | if (elf_file.base.options.z_notext) { | 558 | if (elf_file.z_notext) { |
| 559 | elf_file.has_text_reloc = true; | 559 | elf_file.has_text_reloc = true; |
| 560 | } else { | 560 | } else { |
| 561 | try self.reportTextRelocError(symbol, rel, elf_file); | 561 | try self.reportTextRelocError(symbol, rel, elf_file); |
| ... | @@ -587,7 +587,7 @@ fn scanReloc( | ... | @@ -587,7 +587,7 @@ fn scanReloc( |
| 587 | 587 | ||
| 588 | .dynrel, .baserel, .ifunc => { | 588 | .dynrel, .baserel, .ifunc => { |
| 589 | if (!is_writeable) { | 589 | if (!is_writeable) { |
| 590 | if (elf_file.base.options.z_notext) { | 590 | if (elf_file.z_notext) { |
| 591 | elf_file.has_text_reloc = true; | 591 | elf_file.has_text_reloc = true; |
| 592 | } else { | 592 | } else { |
| 593 | try self.reportTextRelocError(symbol, rel, elf_file); | 593 | try self.reportTextRelocError(symbol, rel, elf_file); |
| ... | @@ -657,11 +657,12 @@ fn dynAbsRelocAction(symbol: *const Symbol, elf_file: *Elf) RelocAction { | ... | @@ -657,11 +657,12 @@ fn dynAbsRelocAction(symbol: *const Symbol, elf_file: *Elf) RelocAction { |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | fn outputType(elf_file: *Elf) u2 { | 659 | fn outputType(elf_file: *Elf) u2 { |
| 660 | const comp = elf_file.base.comp; | ||
| 660 | assert(!elf_file.isRelocatable()); | 661 | assert(!elf_file.isRelocatable()); |
| 661 | return switch (elf_file.base.comp.config.output_mode) { | 662 | return switch (elf_file.base.comp.config.output_mode) { |
| 662 | .Obj => unreachable, | 663 | .Obj => unreachable, |
| 663 | .Lib => 0, | 664 | .Lib => 0, |
| 664 | .Exe => if (elf_file.base.options.pie) 1 else 2, | 665 | .Exe => if (comp.config.pie) 1 else 2, |
| 665 | }; | 666 | }; |
| 666 | } | 667 | } |
| 667 | 668 | ||
| ... | @@ -979,7 +980,7 @@ fn resolveDynAbsReloc( | ... | @@ -979,7 +980,7 @@ fn resolveDynAbsReloc( |
| 979 | => try writer.writeInt(i32, @as(i32, @truncate(S + A)), .little), | 980 | => try writer.writeInt(i32, @as(i32, @truncate(S + A)), .little), |
| 980 | 981 | ||
| 981 | .dyn_copyrel => { | 982 | .dyn_copyrel => { |
| 982 | if (is_writeable or elf_file.base.options.z_nocopyreloc) { | 983 | if (is_writeable or elf_file.z_nocopyreloc) { |
| 983 | elf_file.addRelaDynAssumeCapacity(.{ | 984 | elf_file.addRelaDynAssumeCapacity(.{ |
| 984 | .offset = P, | 985 | .offset = P, |
| 985 | .sym = target.extra(elf_file).?.dynamic, | 986 | .sym = target.extra(elf_file).?.dynamic, |
src/link/Elf/Object.zig+1-1| ... | @@ -299,7 +299,7 @@ fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { | ... | @@ -299,7 +299,7 @@ fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { |
| 299 | if (mem.startsWith(u8, name, ".note")) break :blk true; | 299 | if (mem.startsWith(u8, name, ".note")) break :blk true; |
| 300 | if (mem.startsWith(u8, name, ".comment")) break :blk true; | 300 | if (mem.startsWith(u8, name, ".comment")) break :blk true; |
| 301 | if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true; | 301 | if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true; |
| 302 | if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and | 302 | if (elf_file.base.debug_format == .strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and |
| 303 | mem.startsWith(u8, name, ".debug")) break :blk true; | 303 | mem.startsWith(u8, name, ".debug")) break :blk true; |
| 304 | break :blk false; | 304 | break :blk false; |
| 305 | }; | 305 | }; |
src/link/Elf/ZigObject.zig+1-1| ... | @@ -97,7 +97,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -97,7 +97,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { |
| 97 | symbol_ptr.esym_index = esym_index; | 97 | symbol_ptr.esym_index = esym_index; |
| 98 | 98 | ||
| 99 | if (elf_file.base.debug_format != .strip) { | 99 | if (elf_file.base.debug_format != .strip) { |
| 100 | self.dwarf = Dwarf.init(gpa, &elf_file.base, .dwarf32); | 100 | self.dwarf = Dwarf.init(&elf_file.base, .dwarf32); |
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 103 | 103 |
src/link/Elf/synthetic_sections.zig+15-9| ... | @@ -32,7 +32,7 @@ pub const DynamicSection = struct { | ... | @@ -32,7 +32,7 @@ pub const DynamicSection = struct { |
| 32 | fn getFlags(dt: DynamicSection, elf_file: *Elf) ?u64 { | 32 | fn getFlags(dt: DynamicSection, elf_file: *Elf) ?u64 { |
| 33 | _ = dt; | 33 | _ = dt; |
| 34 | var flags: u64 = 0; | 34 | var flags: u64 = 0; |
| 35 | if (elf_file.base.options.z_now) { | 35 | if (elf_file.z_now) { |
| 36 | flags |= elf.DF_BIND_NOW; | 36 | flags |= elf.DF_BIND_NOW; |
| 37 | } | 37 | } |
| 38 | for (elf_file.got.entries.items) |entry| switch (entry.tag) { | 38 | for (elf_file.got.entries.items) |entry| switch (entry.tag) { |
| ... | @@ -49,15 +49,16 @@ pub const DynamicSection = struct { | ... | @@ -49,15 +49,16 @@ pub const DynamicSection = struct { |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | fn getFlags1(dt: DynamicSection, elf_file: *Elf) ?u64 { | 51 | fn getFlags1(dt: DynamicSection, elf_file: *Elf) ?u64 { |
| 52 | const comp = elf_file.base.comp; | ||
| 52 | _ = dt; | 53 | _ = dt; |
| 53 | var flags_1: u64 = 0; | 54 | var flags_1: u64 = 0; |
| 54 | if (elf_file.base.options.z_now) { | 55 | if (elf_file.z_now) { |
| 55 | flags_1 |= elf.DF_1_NOW; | 56 | flags_1 |= elf.DF_1_NOW; |
| 56 | } | 57 | } |
| 57 | if (elf_file.isExe() and elf_file.base.options.pie) { | 58 | if (elf_file.isExe() and comp.config.pie) { |
| 58 | flags_1 |= elf.DF_1_PIE; | 59 | flags_1 |= elf.DF_1_PIE; |
| 59 | } | 60 | } |
| 60 | // if (elf_file.base.options.z_nodlopen) { | 61 | // if (elf_file.z_nodlopen) { |
| 61 | // flags_1 |= elf.DF_1_NOOPEN; | 62 | // flags_1 |= elf.DF_1_NOOPEN; |
| 62 | // } | 63 | // } |
| 63 | return if (flags_1 > 0) flags_1 else null; | 64 | return if (flags_1 > 0) flags_1 else null; |
| ... | @@ -246,12 +247,13 @@ pub const ZigGotSection = struct { | ... | @@ -246,12 +247,13 @@ pub const ZigGotSection = struct { |
| 246 | } | 247 | } |
| 247 | 248 | ||
| 248 | pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index { | 249 | pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index { |
| 250 | const comp = elf_file.base.comp; | ||
| 249 | const index = try zig_got.allocateEntry(elf_file.base.allocator); | 251 | const index = try zig_got.allocateEntry(elf_file.base.allocator); |
| 250 | const entry = &zig_got.entries.items[index]; | 252 | const entry = &zig_got.entries.items[index]; |
| 251 | entry.* = sym_index; | 253 | entry.* = sym_index; |
| 252 | const symbol = elf_file.symbol(sym_index); | 254 | const symbol = elf_file.symbol(sym_index); |
| 253 | symbol.flags.has_zig_got = true; | 255 | symbol.flags.has_zig_got = true; |
| 254 | if (elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) { | 256 | if (elf_file.isDynLib() or (elf_file.isExe() and comp.config.pie)) { |
| 255 | zig_got.flags.needs_rela = true; | 257 | zig_got.flags.needs_rela = true; |
| 256 | } | 258 | } |
| 257 | if (symbol.extra(elf_file)) |extra| { | 259 | if (symbol.extra(elf_file)) |extra| { |
| ... | @@ -478,6 +480,7 @@ pub const GotSection = struct { | ... | @@ -478,6 +480,7 @@ pub const GotSection = struct { |
| 478 | } | 480 | } |
| 479 | 481 | ||
| 480 | pub fn addGotSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index { | 482 | pub fn addGotSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index { |
| 483 | const comp = elf_file.base.comp; | ||
| 481 | const index = try got.allocateEntry(elf_file.base.allocator); | 484 | const index = try got.allocateEntry(elf_file.base.allocator); |
| 482 | const entry = &got.entries.items[index]; | 485 | const entry = &got.entries.items[index]; |
| 483 | entry.tag = .got; | 486 | entry.tag = .got; |
| ... | @@ -485,7 +488,7 @@ pub const GotSection = struct { | ... | @@ -485,7 +488,7 @@ pub const GotSection = struct { |
| 485 | const symbol = elf_file.symbol(sym_index); | 488 | const symbol = elf_file.symbol(sym_index); |
| 486 | symbol.flags.has_got = true; | 489 | symbol.flags.has_got = true; |
| 487 | if (symbol.flags.import or symbol.isIFunc(elf_file) or | 490 | if (symbol.flags.import or symbol.isIFunc(elf_file) or |
| 488 | ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and !symbol.isAbs(elf_file))) | 491 | ((elf_file.isDynLib() or (elf_file.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file))) |
| 489 | { | 492 | { |
| 490 | got.flags.needs_rela = true; | 493 | got.flags.needs_rela = true; |
| 491 | } | 494 | } |
| ... | @@ -561,6 +564,7 @@ pub const GotSection = struct { | ... | @@ -561,6 +564,7 @@ pub const GotSection = struct { |
| 561 | } | 564 | } |
| 562 | 565 | ||
| 563 | pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void { | 566 | pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void { |
| 567 | const comp = elf_file.base.comp; | ||
| 564 | const is_dyn_lib = elf_file.isDynLib(); | 568 | const is_dyn_lib = elf_file.isDynLib(); |
| 565 | const apply_relocs = true; // TODO add user option for this | 569 | const apply_relocs = true; // TODO add user option for this |
| 566 | 570 | ||
| ... | @@ -576,7 +580,7 @@ pub const GotSection = struct { | ... | @@ -576,7 +580,7 @@ pub const GotSection = struct { |
| 576 | if (symbol.?.flags.import) break :blk 0; | 580 | if (symbol.?.flags.import) break :blk 0; |
| 577 | if (symbol.?.isIFunc(elf_file)) | 581 | if (symbol.?.isIFunc(elf_file)) |
| 578 | break :blk if (apply_relocs) value else 0; | 582 | break :blk if (apply_relocs) value else 0; |
| 579 | if ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and | 583 | if ((elf_file.isDynLib() or (elf_file.isExe() and comp.config.pie)) and |
| 580 | !symbol.?.isAbs(elf_file)) | 584 | !symbol.?.isAbs(elf_file)) |
| 581 | { | 585 | { |
| 582 | break :blk if (apply_relocs) value else 0; | 586 | break :blk if (apply_relocs) value else 0; |
| ... | @@ -623,6 +627,7 @@ pub const GotSection = struct { | ... | @@ -623,6 +627,7 @@ pub const GotSection = struct { |
| 623 | } | 627 | } |
| 624 | 628 | ||
| 625 | pub fn addRela(got: GotSection, elf_file: *Elf) !void { | 629 | pub fn addRela(got: GotSection, elf_file: *Elf) !void { |
| 630 | const comp = elf_file.base.comp; | ||
| 626 | const is_dyn_lib = elf_file.isDynLib(); | 631 | const is_dyn_lib = elf_file.isDynLib(); |
| 627 | try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, got.numRela(elf_file)); | 632 | try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, got.numRela(elf_file)); |
| 628 | 633 | ||
| ... | @@ -652,7 +657,7 @@ pub const GotSection = struct { | ... | @@ -652,7 +657,7 @@ pub const GotSection = struct { |
| 652 | }); | 657 | }); |
| 653 | continue; | 658 | continue; |
| 654 | } | 659 | } |
| 655 | if ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and | 660 | if ((elf_file.isDynLib() or (elf_file.isExe() and comp.config.pie)) and |
| 656 | !symbol.?.isAbs(elf_file)) | 661 | !symbol.?.isAbs(elf_file)) |
| 657 | { | 662 | { |
| 658 | elf_file.addRelaDynAssumeCapacity(.{ | 663 | elf_file.addRelaDynAssumeCapacity(.{ |
| ... | @@ -725,6 +730,7 @@ pub const GotSection = struct { | ... | @@ -725,6 +730,7 @@ pub const GotSection = struct { |
| 725 | } | 730 | } |
| 726 | 731 | ||
| 727 | pub fn numRela(got: GotSection, elf_file: *Elf) usize { | 732 | pub fn numRela(got: GotSection, elf_file: *Elf) usize { |
| 733 | const comp = elf_file.base.comp; | ||
| 728 | const is_dyn_lib = elf_file.isDynLib(); | 734 | const is_dyn_lib = elf_file.isDynLib(); |
| 729 | var num: usize = 0; | 735 | var num: usize = 0; |
| 730 | for (got.entries.items) |entry| { | 736 | for (got.entries.items) |entry| { |
| ... | @@ -734,7 +740,7 @@ pub const GotSection = struct { | ... | @@ -734,7 +740,7 @@ pub const GotSection = struct { |
| 734 | }; | 740 | }; |
| 735 | switch (entry.tag) { | 741 | switch (entry.tag) { |
| 736 | .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or | 742 | .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or |
| 737 | ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and | 743 | ((elf_file.isDynLib() or (elf_file.isExe() and comp.config.pie)) and |
| 738 | !symbol.?.isAbs(elf_file))) | 744 | !symbol.?.isAbs(elf_file))) |
| 739 | { | 745 | { |
| 740 | num += 1; | 746 | num += 1; |
src/link/MachO.zig+20-16| ... | @@ -252,7 +252,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO { | ... | @@ -252,7 +252,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 252 | 252 | ||
| 253 | self.d_sym = .{ | 253 | self.d_sym = .{ |
| 254 | .allocator = gpa, | 254 | .allocator = gpa, |
| 255 | .dwarf = link.File.Dwarf.init(gpa, &self.base, .dwarf32), | 255 | .dwarf = link.File.Dwarf.init(&self.base, .dwarf32), |
| 256 | .file = d_sym_file, | 256 | .file = d_sym_file, |
| 257 | }; | 257 | }; |
| 258 | } | 258 | } |
| ... | @@ -573,7 +573,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -573,7 +573,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 573 | 573 | ||
| 574 | try self.writeLinkeditSegmentData(); | 574 | try self.writeLinkeditSegmentData(); |
| 575 | 575 | ||
| 576 | var codesig: ?CodeSignature = if (requiresCodeSignature(&self.base.options)) blk: { | 576 | var codesig: ?CodeSignature = if (self.requiresCodeSignature()) blk: { |
| 577 | // Preallocate space for the code signature. | 577 | // Preallocate space for the code signature. |
| 578 | // We need to do this at this stage so that we have the load commands with proper values | 578 | // We need to do this at this stage so that we have the load commands with proper values |
| 579 | // written out to the file. | 579 | // written out to the file. |
| ... | @@ -619,12 +619,12 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -619,12 +619,12 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 619 | }); | 619 | }); |
| 620 | }, | 620 | }, |
| 621 | .Lib => if (self.base.comp.config.link_mode == .Dynamic) { | 621 | .Lib => if (self.base.comp.config.link_mode == .Dynamic) { |
| 622 | try load_commands.writeDylibIdLC(gpa, &self.base.options, lc_writer); | 622 | try load_commands.writeDylibIdLC(self, lc_writer); |
| 623 | }, | 623 | }, |
| 624 | else => {}, | 624 | else => {}, |
| 625 | } | 625 | } |
| 626 | 626 | ||
| 627 | try load_commands.writeRpathLCs(gpa, &self.base.options, lc_writer); | 627 | try load_commands.writeRpathLCs(self, lc_writer); |
| 628 | try lc_writer.writeStruct(macho.source_version_command{ | 628 | try lc_writer.writeStruct(macho.source_version_command{ |
| 629 | .version = 0, | 629 | .version = 0, |
| 630 | }); | 630 | }); |
| ... | @@ -713,7 +713,7 @@ pub fn resolveLibSystem( | ... | @@ -713,7 +713,7 @@ pub fn resolveLibSystem( |
| 713 | success: { | 713 | success: { |
| 714 | if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { | 714 | if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { |
| 715 | .sdk => { | 715 | .sdk => { |
| 716 | const dir = try fs.path.join(arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" }); | 716 | const dir = try fs.path.join(arena, &[_][]const u8{ comp.sysroot.?, "usr", "lib" }); |
| 717 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success; | 717 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success; |
| 718 | }, | 718 | }, |
| 719 | .vendored => { | 719 | .vendored => { |
| ... | @@ -1156,7 +1156,8 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void { | ... | @@ -1156,7 +1156,8 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void { |
| 1156 | // 2) afterwards, we parse dependents of the included dylibs | 1156 | // 2) afterwards, we parse dependents of the included dylibs |
| 1157 | // TODO this should not be performed if the user specifies `-flat_namespace` flag. | 1157 | // TODO this should not be performed if the user specifies `-flat_namespace` flag. |
| 1158 | // See ld64 manpages. | 1158 | // See ld64 manpages. |
| 1159 | const gpa = self.base.comp.gpa; | 1159 | const comp = self.base.comp; |
| 1160 | const gpa = comp.gpa; | ||
| 1160 | 1161 | ||
| 1161 | while (dependent_libs.readItem()) |dep_id| { | 1162 | while (dependent_libs.readItem()) |dep_id| { |
| 1162 | defer dep_id.id.deinit(gpa); | 1163 | defer dep_id.id.deinit(gpa); |
| ... | @@ -1176,7 +1177,7 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void { | ... | @@ -1176,7 +1177,7 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void { |
| 1176 | var checked_paths = std.ArrayList([]const u8).init(arena); | 1177 | var checked_paths = std.ArrayList([]const u8).init(arena); |
| 1177 | 1178 | ||
| 1178 | success: { | 1179 | success: { |
| 1179 | if (self.base.options.sysroot) |root| { | 1180 | if (comp.sysroot) |root| { |
| 1180 | const dir = try fs.path.join(arena, &[_][]const u8{ root, dirname }); | 1181 | const dir = try fs.path.join(arena, &[_][]const u8{ root, dirname }); |
| 1181 | if (try accessLibPath(gpa, &test_path, &checked_paths, dir, stem)) break :success; | 1182 | if (try accessLibPath(gpa, &test_path, &checked_paths, dir, stem)) break :success; |
| 1182 | } | 1183 | } |
| ... | @@ -1713,12 +1714,12 @@ pub fn resolveSymbols(self: *MachO) !void { | ... | @@ -1713,12 +1714,12 @@ pub fn resolveSymbols(self: *MachO) !void { |
| 1713 | // we search for it in libraries should there be no object files specified | 1714 | // we search for it in libraries should there be no object files specified |
| 1714 | // on the linker line. | 1715 | // on the linker line. |
| 1715 | if (output_mode == .Exe) { | 1716 | if (output_mode == .Exe) { |
| 1716 | const entry_name = self.base.options.entry orelse load_commands.default_entry_point; | 1717 | const entry_name = comp.config.entry.?; |
| 1717 | _ = try self.addUndefined(entry_name, .{}); | 1718 | _ = try self.addUndefined(entry_name, .{}); |
| 1718 | } | 1719 | } |
| 1719 | 1720 | ||
| 1720 | // Force resolution of any symbols requested by the user. | 1721 | // Force resolution of any symbols requested by the user. |
| 1721 | for (self.base.options.force_undefined_symbols.keys()) |sym_name| { | 1722 | for (self.base.force_undefined_symbols.keys()) |sym_name| { |
| 1722 | _ = try self.addUndefined(sym_name, .{}); | 1723 | _ = try self.addUndefined(sym_name, .{}); |
| 1723 | } | 1724 | } |
| 1724 | 1725 | ||
| ... | @@ -4367,7 +4368,7 @@ fn writeSymtab(self: *MachO) !SymtabCtx { | ... | @@ -4367,7 +4368,7 @@ fn writeSymtab(self: *MachO) !SymtabCtx { |
| 4367 | 4368 | ||
| 4368 | // We generate stabs last in order to ensure that the strtab always has debug info | 4369 | // We generate stabs last in order to ensure that the strtab always has debug info |
| 4369 | // strings trailing | 4370 | // strings trailing |
| 4370 | if (!self.base.options.strip) { | 4371 | if (self.base.debug_format != .strip) { |
| 4371 | for (self.objects.items) |object| { | 4372 | for (self.objects.items) |object| { |
| 4372 | assert(self.d_sym == null); // TODO | 4373 | assert(self.d_sym == null); // TODO |
| 4373 | try self.generateSymbolStabs(object, &locals); | 4374 | try self.generateSymbolStabs(object, &locals); |
| ... | @@ -5171,7 +5172,8 @@ pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { | ... | @@ -5171,7 +5172,8 @@ pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { |
| 5171 | /// Returns symbol location corresponding to the set entrypoint if any. | 5172 | /// Returns symbol location corresponding to the set entrypoint if any. |
| 5172 | /// Asserts output mode is executable. | 5173 | /// Asserts output mode is executable. |
| 5173 | pub fn getEntryPoint(self: MachO) ?SymbolWithLoc { | 5174 | pub fn getEntryPoint(self: MachO) ?SymbolWithLoc { |
| 5174 | const entry_name = self.base.options.entry orelse load_commands.default_entry_point; | 5175 | const comp = self.base.comp; |
| 5176 | const entry_name = comp.config.entry orelse return null; | ||
| 5175 | const global = self.getGlobal(entry_name) orelse return null; | 5177 | const global = self.getGlobal(entry_name) orelse return null; |
| 5176 | return global; | 5178 | return global; |
| 5177 | } | 5179 | } |
| ... | @@ -5189,11 +5191,13 @@ pub inline fn getPageSize(cpu_arch: std.Target.Cpu.Arch) u16 { | ... | @@ -5189,11 +5191,13 @@ pub inline fn getPageSize(cpu_arch: std.Target.Cpu.Arch) u16 { |
| 5189 | }; | 5191 | }; |
| 5190 | } | 5192 | } |
| 5191 | 5193 | ||
| 5192 | pub fn requiresCodeSignature(options: *const link.Options) bool { | 5194 | pub fn requiresCodeSignature(m: *MachO) bool { |
| 5193 | if (options.entitlements) |_| return true; | 5195 | if (m.entitlements) |_| return true; |
| 5194 | const cpu_arch = options.target.cpu.arch; | 5196 | const comp = m.base.comp; |
| 5195 | const os_tag = options.target.os.tag; | 5197 | const target = comp.root_mod.resolved_target.result; |
| 5196 | const abi = options.target.abi; | 5198 | const cpu_arch = target.cpu.arch; |
| 5199 | const os_tag = target.os.tag; | ||
| 5200 | const abi = target.abi; | ||
| 5197 | if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) return true; | 5201 | if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) return true; |
| 5198 | return false; | 5202 | return false; |
| 5199 | } | 5203 | } |
src/link/MachO/DebugSymbols.zig+3-4| ... | @@ -198,10 +198,10 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) u64 | ... | @@ -198,10 +198,10 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) u64 |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { | 200 | pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 201 | const comp = macho_file.base.comp; | ||
| 201 | // TODO This linker code currently assumes there is only 1 compilation unit | 202 | // TODO This linker code currently assumes there is only 1 compilation unit |
| 202 | // and it corresponds to the Zig source code. | 203 | // and it corresponds to the Zig source code. |
| 203 | const options = macho_file.base.options; | 204 | const zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| 204 | const module = options.module orelse return error.LinkingWithoutZigSourceUnimplemented; | ||
| 205 | 205 | ||
| 206 | for (self.relocs.items) |*reloc| { | 206 | for (self.relocs.items) |*reloc| { |
| 207 | const sym = switch (reloc.type) { | 207 | const sym = switch (reloc.type) { |
| ... | @@ -245,7 +245,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -245,7 +245,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 245 | const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?]; | 245 | const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?]; |
| 246 | const low_pc = text_section.addr; | 246 | const low_pc = text_section.addr; |
| 247 | const high_pc = text_section.addr + text_section.size; | 247 | const high_pc = text_section.addr + text_section.size; |
| 248 | try self.dwarf.writeDbgInfoHeader(module, low_pc, high_pc); | 248 | try self.dwarf.writeDbgInfoHeader(zcu, low_pc, high_pc); |
| 249 | self.debug_info_header_dirty = false; | 249 | self.debug_info_header_dirty = false; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| ... | @@ -572,6 +572,5 @@ const trace = @import("../../tracy.zig").trace; | ... | @@ -572,6 +572,5 @@ const trace = @import("../../tracy.zig").trace; |
| 572 | const Allocator = mem.Allocator; | 572 | const Allocator = mem.Allocator; |
| 573 | const Dwarf = @import("../Dwarf.zig"); | 573 | const Dwarf = @import("../Dwarf.zig"); |
| 574 | const MachO = @import("../MachO.zig"); | 574 | const MachO = @import("../MachO.zig"); |
| 575 | const Module = @import("../../Module.zig"); | ||
| 576 | const StringTable = @import("../StringTable.zig"); | 575 | const StringTable = @import("../StringTable.zig"); |
| 577 | const Type = @import("../../type.zig").Type; | 576 | const Type = @import("../../type.zig").Type; |
src/link/MachO/dead_strip.zig+1-1| ... | @@ -60,7 +60,7 @@ fn collectRoots(macho_file: *MachO, roots: *AtomTable) !void { | ... | @@ -60,7 +60,7 @@ fn collectRoots(macho_file: *MachO, roots: *AtomTable) !void { |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | // Add all symbols force-defined by the user. | 62 | // Add all symbols force-defined by the user. |
| 63 | for (macho_file.base.options.force_undefined_symbols.keys()) |sym_name| { | 63 | for (macho_file.base.force_undefined_symbols.keys()) |sym_name| { |
| 64 | const global_index = macho_file.resolver.get(sym_name).?; | 64 | const global_index = macho_file.resolver.get(sym_name).?; |
| 65 | const global = macho_file.globals.items[global_index]; | 65 | const global = macho_file.globals.items[global_index]; |
| 66 | const sym = macho_file.getSymbol(global); | 66 | const sym = macho_file.getSymbol(global); |
src/link/MachO/load_commands.zig+17-17| ... | @@ -1,6 +1,3 @@ | ... | @@ -1,6 +1,3 @@ |
| 1 | /// Default implicit entrypoint symbol name. | ||
| 2 | pub const default_entry_point: []const u8 = "_main"; | ||
| 3 | |||
| 4 | /// Default path to dyld. | 1 | /// Default path to dyld. |
| 5 | pub const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld"; | 2 | pub const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld"; |
| 6 | 3 | ||
| ... | @@ -17,7 +14,9 @@ const CalcLCsSizeCtx = struct { | ... | @@ -17,7 +14,9 @@ const CalcLCsSizeCtx = struct { |
| 17 | wants_function_starts: bool = true, | 14 | wants_function_starts: bool = true, |
| 18 | }; | 15 | }; |
| 19 | 16 | ||
| 20 | fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx, assume_max_path_len: bool) !u32 { | 17 | fn calcLCsSize(m: *MachO, ctx: CalcLCsSizeCtx, assume_max_path_len: bool) !u32 { |
| 18 | const comp = m.base.comp; | ||
| 19 | const gpa = comp.gpa; | ||
| 21 | var has_text_segment: bool = false; | 20 | var has_text_segment: bool = false; |
| 22 | var sizeofcmds: u64 = 0; | 21 | var sizeofcmds: u64 = 0; |
| 23 | for (ctx.segments) |seg| { | 22 | for (ctx.segments) |seg| { |
| ... | @@ -46,15 +45,15 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx | ... | @@ -46,15 +45,15 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx |
| 46 | false, | 45 | false, |
| 47 | ); | 46 | ); |
| 48 | // LC_MAIN | 47 | // LC_MAIN |
| 49 | if (options.output_mode == .Exe) { | 48 | if (comp.config.output_mode == .Exe) { |
| 50 | sizeofcmds += @sizeOf(macho.entry_point_command); | 49 | sizeofcmds += @sizeOf(macho.entry_point_command); |
| 51 | } | 50 | } |
| 52 | // LC_ID_DYLIB | 51 | // LC_ID_DYLIB |
| 53 | if (options.output_mode == .Lib and options.link_mode == .Dynamic) { | 52 | if (comp.config.output_mode == .Lib and comp.config.link_mode == .Dynamic) { |
| 54 | sizeofcmds += blk: { | 53 | sizeofcmds += blk: { |
| 55 | const emit = options.emit.?; | 54 | const emit = m.base.emit; |
| 56 | const install_name = options.install_name orelse try emit.directory.join(gpa, &.{emit.sub_path}); | 55 | const install_name = m.install_name orelse try emit.directory.join(gpa, &.{emit.sub_path}); |
| 57 | defer if (options.install_name == null) gpa.free(install_name); | 56 | defer if (m.install_name == null) gpa.free(install_name); |
| 58 | break :blk calcInstallNameLen( | 57 | break :blk calcInstallNameLen( |
| 59 | @sizeOf(macho.dylib_command), | 58 | @sizeOf(macho.dylib_command), |
| 60 | install_name, | 59 | install_name, |
| ... | @@ -64,7 +63,7 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx | ... | @@ -64,7 +63,7 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx |
| 64 | } | 63 | } |
| 65 | // LC_RPATH | 64 | // LC_RPATH |
| 66 | { | 65 | { |
| 67 | var it = RpathIterator.init(gpa, options.rpath_list); | 66 | var it = RpathIterator.init(gpa, m.rpath_list); |
| 68 | defer it.deinit(); | 67 | defer it.deinit(); |
| 69 | while (try it.next()) |rpath| { | 68 | while (try it.next()) |rpath| { |
| 70 | sizeofcmds += calcInstallNameLen( | 69 | sizeofcmds += calcInstallNameLen( |
| ... | @@ -78,7 +77,8 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx | ... | @@ -78,7 +77,8 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx |
| 78 | sizeofcmds += @sizeOf(macho.source_version_command); | 77 | sizeofcmds += @sizeOf(macho.source_version_command); |
| 79 | // LC_BUILD_VERSION or LC_VERSION_MIN_ or nothing | 78 | // LC_BUILD_VERSION or LC_VERSION_MIN_ or nothing |
| 80 | { | 79 | { |
| 81 | const platform = Platform.fromTarget(options.target); | 80 | const target = comp.root_mod.resolved_target.result; |
| 81 | const platform = Platform.fromTarget(target); | ||
| 82 | if (platform.isBuildVersionCompatible()) { | 82 | if (platform.isBuildVersionCompatible()) { |
| 83 | // LC_BUILD_VERSION | 83 | // LC_BUILD_VERSION |
| 84 | sizeofcmds += @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version); | 84 | sizeofcmds += @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version); |
| ... | @@ -100,19 +100,19 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx | ... | @@ -100,19 +100,19 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx |
| 100 | ); | 100 | ); |
| 101 | } | 101 | } |
| 102 | // LC_CODE_SIGNATURE | 102 | // LC_CODE_SIGNATURE |
| 103 | if (MachO.requiresCodeSignature(options)) { | 103 | if (m.requiresCodeSignature()) { |
| 104 | sizeofcmds += @sizeOf(macho.linkedit_data_command); | 104 | sizeofcmds += @sizeOf(macho.linkedit_data_command); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | return @as(u32, @intCast(sizeofcmds)); | 107 | return @intCast(sizeofcmds); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | pub fn calcMinHeaderPad(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx) !u64 { | 110 | pub fn calcMinHeaderPad(m: *MachO, ctx: CalcLCsSizeCtx) !u64 { |
| 111 | var padding: u32 = (try calcLCsSize(gpa, options, ctx, false)) + (options.headerpad_size orelse 0); | 111 | var padding: u32 = (try calcLCsSize(m, ctx, false)) + m.headerpad_size; |
| 112 | log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); | 112 | log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); |
| 113 | 113 | ||
| 114 | if (options.headerpad_max_install_names) { | 114 | if (m.headerpad_max_install_names) { |
| 115 | const min_headerpad_size: u32 = try calcLCsSize(gpa, options, ctx, true); | 115 | const min_headerpad_size: u32 = try calcLCsSize(m, ctx, true); |
| 116 | log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{ | 116 | log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{ |
| 117 | min_headerpad_size + @sizeOf(macho.mach_header_64), | 117 | min_headerpad_size + @sizeOf(macho.mach_header_64), |
| 118 | }); | 118 | }); |
src/link/MachO/zld.zig+4-5| ... | @@ -499,7 +499,7 @@ pub fn linkWithZld( | ... | @@ -499,7 +499,7 @@ pub fn linkWithZld( |
| 499 | } | 499 | } |
| 500 | 500 | ||
| 501 | // Write code signature padding if required | 501 | // Write code signature padding if required |
| 502 | var codesig: ?CodeSignature = if (MachO.requiresCodeSignature(&macho_file.base.options)) blk: { | 502 | var codesig: ?CodeSignature = if (macho_file.requiresCodeSignature()) blk: { |
| 503 | // Preallocate space for the code signature. | 503 | // Preallocate space for the code signature. |
| 504 | // We need to do this at this stage so that we have the load commands with proper values | 504 | // We need to do this at this stage so that we have the load commands with proper values |
| 505 | // written out to the file. | 505 | // written out to the file. |
| ... | @@ -547,12 +547,12 @@ pub fn linkWithZld( | ... | @@ -547,12 +547,12 @@ pub fn linkWithZld( |
| 547 | }); | 547 | }); |
| 548 | }, | 548 | }, |
| 549 | .Lib => if (link_mode == .Dynamic) { | 549 | .Lib => if (link_mode == .Dynamic) { |
| 550 | try load_commands.writeDylibIdLC(gpa, &macho_file.base.options, lc_writer); | 550 | try load_commands.writeDylibIdLC(macho_file, lc_writer); |
| 551 | }, | 551 | }, |
| 552 | else => {}, | 552 | else => {}, |
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | try load_commands.writeRpathLCs(gpa, &macho_file.base.options, lc_writer); | 555 | try load_commands.writeRpathLCs(macho_file, lc_writer); |
| 556 | try lc_writer.writeStruct(macho.source_version_command{ | 556 | try lc_writer.writeStruct(macho.source_version_command{ |
| 557 | .version = 0, | 557 | .version = 0, |
| 558 | }); | 558 | }); |
| ... | @@ -1072,11 +1072,10 @@ fn calcSectionSizes(macho_file: *MachO) !void { | ... | @@ -1072,11 +1072,10 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 1072 | } | 1072 | } |
| 1073 | 1073 | ||
| 1074 | fn allocateSegments(macho_file: *MachO) !void { | 1074 | fn allocateSegments(macho_file: *MachO) !void { |
| 1075 | const gpa = macho_file.base.allocator; | ||
| 1076 | for (macho_file.segments.items, 0..) |*segment, segment_index| { | 1075 | for (macho_file.segments.items, 0..) |*segment, segment_index| { |
| 1077 | const is_text_segment = mem.eql(u8, segment.segName(), "__TEXT"); | 1076 | const is_text_segment = mem.eql(u8, segment.segName(), "__TEXT"); |
| 1078 | const base_size = if (is_text_segment) | 1077 | const base_size = if (is_text_segment) |
| 1079 | try load_commands.calcMinHeaderPad(gpa, &macho_file.base.options, .{ | 1078 | try load_commands.calcMinHeaderPad(macho_file, .{ |
| 1080 | .segments = macho_file.segments.items, | 1079 | .segments = macho_file.segments.items, |
| 1081 | .dylibs = macho_file.dylibs.items, | 1080 | .dylibs = macho_file.dylibs.items, |
| 1082 | .referenced_dylibs = macho_file.referenced_dylibs.keys(), | 1081 | .referenced_dylibs = macho_file.referenced_dylibs.keys(), |
src/link/NvPtx.zig+2-1| ... | @@ -57,6 +57,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*NvPtx { | ... | @@ -57,6 +57,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*NvPtx { |
| 57 | .build_id = options.build_id, | 57 | .build_id = options.build_id, |
| 58 | .rpath_list = options.rpath_list, | 58 | .rpath_list = options.rpath_list, |
| 59 | .force_undefined_symbols = options.force_undefined_symbols, | 59 | .force_undefined_symbols = options.force_undefined_symbols, |
| 60 | .debug_format = options.debug_format orelse .{ .dwarf = .@"32" }, | ||
| 60 | .function_sections = options.function_sections, | 61 | .function_sections = options.function_sections, |
| 61 | .data_sections = options.data_sections, | 62 | .data_sections = options.data_sections, |
| 62 | }, | 63 | }, |
| ... | @@ -66,7 +67,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*NvPtx { | ... | @@ -66,7 +67,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*NvPtx { |
| 66 | return nvptx; | 67 | return nvptx; |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | pub fn open(arena: Allocator, options: link.FileOpenOptions) !*NvPtx { | 70 | pub fn open(arena: Allocator, options: link.File.OpenOptions) !*NvPtx { |
| 70 | const target = options.comp.root_mod.resolved_target.result; | 71 | const target = options.comp.root_mod.resolved_target.result; |
| 71 | assert(target.ofmt == .nvptx); | 72 | assert(target.ofmt == .nvptx); |
| 72 | return createEmpty(arena, options); | 73 | return createEmpty(arena, options); |
src/link/Plan9.zig+21-11| ... | @@ -295,26 +295,36 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases { | ... | @@ -295,26 +295,36 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases { |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Plan9 { | 297 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Plan9 { |
| 298 | _ = arena; | 298 | const comp = options.comp; |
| 299 | const target = options.comp.root_mod.resolved_target.result; | 299 | const target = comp.root_mod.resolved_target.result; |
| 300 | const gpa = options.comp.gpa; | 300 | const gpa = comp.gpa; |
| 301 | const optimize_mode = comp.root_mod.optimize_mode; | ||
| 302 | const output_mode = comp.config.output_mode; | ||
| 301 | 303 | ||
| 302 | const sixtyfour_bit: bool = switch (options.target.ptrBitWidth()) { | 304 | const sixtyfour_bit: bool = switch (target.ptrBitWidth()) { |
| 303 | 0...32 => false, | 305 | 0...32 => false, |
| 304 | 33...64 => true, | 306 | 33...64 => true, |
| 305 | else => return error.UnsupportedP9Architecture, | 307 | else => return error.UnsupportedP9Architecture, |
| 306 | }; | 308 | }; |
| 307 | 309 | ||
| 308 | const arena_allocator = std.heap.ArenaAllocator.init(gpa); | 310 | const self = try arena.create(Plan9); |
| 309 | |||
| 310 | const self = try gpa.create(Plan9); | ||
| 311 | self.* = .{ | 311 | self.* = .{ |
| 312 | .path_arena = arena_allocator, | 312 | .path_arena = std.heap.ArenaAllocator.init(gpa), |
| 313 | .base = .{ | 313 | .base = .{ |
| 314 | .tag = .plan9, | 314 | .tag = .plan9, |
| 315 | .options = options, | 315 | .comp = comp, |
| 316 | .allocator = gpa, | 316 | .emit = options.emit, |
| 317 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), | ||
| 318 | .stack_size = options.stack_size orelse 16777216, | ||
| 319 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, | ||
| 317 | .file = null, | 320 | .file = null, |
| 321 | .disable_lld_caching = options.disable_lld_caching, | ||
| 322 | .build_id = options.build_id, | ||
| 323 | .rpath_list = options.rpath_list, | ||
| 324 | .force_undefined_symbols = options.force_undefined_symbols, | ||
| 325 | .debug_format = options.debug_format orelse .{ .dwarf = .@"32" }, | ||
| 326 | .function_sections = options.function_sections, | ||
| 327 | .data_sections = options.data_sections, | ||
| 318 | }, | 328 | }, |
| 319 | .sixtyfour_bit = sixtyfour_bit, | 329 | .sixtyfour_bit = sixtyfour_bit, |
| 320 | .bases = undefined, | 330 | .bases = undefined, |
| ... | @@ -602,7 +612,7 @@ pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) li | ... | @@ -602,7 +612,7 @@ pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) li |
| 602 | const use_lld = build_options.have_llvm and self.base.comp.config.use_lld; | 612 | const use_lld = build_options.have_llvm and self.base.comp.config.use_lld; |
| 603 | assert(!use_lld); | 613 | assert(!use_lld); |
| 604 | 614 | ||
| 605 | switch (self.base.options.effectiveOutputMode()) { | 615 | switch (link.File.effectiveOutputMode(use_lld, comp.config.output_mode)) { |
| 606 | .Exe => {}, | 616 | .Exe => {}, |
| 607 | // plan9 object files are totally different | 617 | // plan9 object files are totally different |
| 608 | .Obj => return error.TODOImplementPlan9Objs, | 618 | .Obj => return error.TODOImplementPlan9Objs, |
src/link/SpirV.zig+2-1| ... | @@ -67,6 +67,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*SpirV { | ... | @@ -67,6 +67,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*SpirV { |
| 67 | .force_undefined_symbols = options.force_undefined_symbols, | 67 | .force_undefined_symbols = options.force_undefined_symbols, |
| 68 | .function_sections = options.function_sections, | 68 | .function_sections = options.function_sections, |
| 69 | .data_sections = options.data_sections, | 69 | .data_sections = options.data_sections, |
| 70 | .debug_format = options.debug_format orelse .{ .dwarf = .@"32" }, | ||
| 70 | }, | 71 | }, |
| 71 | .object = codegen.Object.init(gpa), | 72 | .object = codegen.Object.init(gpa), |
| 72 | }; | 73 | }; |
| ... | @@ -102,7 +103,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*SpirV { | ... | @@ -102,7 +103,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*SpirV { |
| 102 | errdefer spirv.base.destroy(); | 103 | errdefer spirv.base.destroy(); |
| 103 | 104 | ||
| 104 | // TODO: read the file and keep valid parts instead of truncating | 105 | // TODO: read the file and keep valid parts instead of truncating |
| 105 | const file = try options.emit.?.directory.handle.createFile(options.emit.sub_path, .{ | 106 | const file = try options.emit.directory.handle.createFile(options.emit.sub_path, .{ |
| 106 | .truncate = true, | 107 | .truncate = true, |
| 107 | .read = true, | 108 | .read = true, |
| 108 | }); | 109 | }); |
src/link/Wasm.zig+149-96| ... | @@ -37,6 +37,13 @@ pub const Relocation = types.Relocation; | ... | @@ -37,6 +37,13 @@ pub const Relocation = types.Relocation; |
| 37 | pub const base_tag: link.File.Tag = .wasm; | 37 | pub const base_tag: link.File.Tag = .wasm; |
| 38 | 38 | ||
| 39 | base: link.File, | 39 | base: link.File, |
| 40 | import_symbols: bool, | ||
| 41 | export_symbol_names: []const []const u8, | ||
| 42 | rdynamic: bool, | ||
| 43 | global_base: ?u64, | ||
| 44 | initial_memory: ?u64, | ||
| 45 | max_memory: ?u64, | ||
| 46 | wasi_emulated_libs: []const wasi_libc.CRTFile, | ||
| 40 | /// Output name of the file | 47 | /// Output name of the file |
| 41 | name: []const u8, | 48 | name: []const u8, |
| 42 | /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. | 49 | /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. |
| ... | @@ -368,13 +375,15 @@ pub const StringTable = struct { | ... | @@ -368,13 +375,15 @@ pub const StringTable = struct { |
| 368 | 375 | ||
| 369 | pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { | 376 | pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { |
| 370 | if (build_options.only_c) unreachable; | 377 | if (build_options.only_c) unreachable; |
| 371 | const gpa = options.comp.gpa; | 378 | const comp = options.comp; |
| 372 | const target = options.comp.root_mod.resolved_target.result; | 379 | const gpa = comp.gpa; |
| 380 | const target = comp.root_mod.resolved_target.result; | ||
| 373 | assert(target.ofmt == .wasm); | 381 | assert(target.ofmt == .wasm); |
| 374 | 382 | ||
| 375 | const use_lld = build_options.have_llvm and options.comp.config.use_lld; | 383 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 376 | const use_llvm = options.comp.config.use_llvm; | 384 | const use_llvm = comp.config.use_llvm; |
| 377 | const output_mode = options.comp.config.output_mode; | 385 | const output_mode = comp.config.output_mode; |
| 386 | const shared_memory = comp.config.shared_memory; | ||
| 378 | 387 | ||
| 379 | const wasm = try createEmpty(arena, options); | 388 | const wasm = try createEmpty(arena, options); |
| 380 | errdefer wasm.base.destroy(); | 389 | errdefer wasm.base.destroy(); |
| ... | @@ -395,7 +404,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { | ... | @@ -395,7 +404,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { |
| 395 | }; | 404 | }; |
| 396 | 405 | ||
| 397 | // TODO: read the file and keep valid parts instead of truncating | 406 | // TODO: read the file and keep valid parts instead of truncating |
| 398 | const file = try options.emit.?.directory.handle.createFile(sub_path, .{ | 407 | const file = try options.emit.directory.handle.createFile(sub_path, .{ |
| 399 | .truncate = true, | 408 | .truncate = true, |
| 400 | .read = true, | 409 | .read = true, |
| 401 | .mode = if (fs.has_executable_bit) | 410 | .mode = if (fs.has_executable_bit) |
| ... | @@ -480,7 +489,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { | ... | @@ -480,7 +489,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { |
| 480 | } | 489 | } |
| 481 | 490 | ||
| 482 | // shared-memory symbols for TLS support | 491 | // shared-memory symbols for TLS support |
| 483 | if (wasm.base.options.shared_memory) { | 492 | if (shared_memory) { |
| 484 | { | 493 | { |
| 485 | const loc = try wasm.createSyntheticSymbol("__tls_base", .global); | 494 | const loc = try wasm.createSyntheticSymbol("__tls_base", .global); |
| 486 | const symbol = loc.getSymbol(wasm); | 495 | const symbol = loc.getSymbol(wasm); |
| ... | @@ -522,14 +531,15 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { | ... | @@ -522,14 +531,15 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Wasm { |
| 522 | } | 531 | } |
| 523 | 532 | ||
| 524 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Wasm { | 533 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Wasm { |
| 525 | const use_llvm = options.comp.config.use_llvm; | 534 | const comp = options.comp; |
| 526 | const output_mode = options.comp.config.output_mode; | 535 | const use_llvm = comp.config.use_llvm; |
| 536 | const output_mode = comp.config.output_mode; | ||
| 527 | 537 | ||
| 528 | const wasm = try arena.create(Wasm); | 538 | const wasm = try arena.create(Wasm); |
| 529 | wasm.* = .{ | 539 | wasm.* = .{ |
| 530 | .base = .{ | 540 | .base = .{ |
| 531 | .tag = .wasm, | 541 | .tag = .wasm, |
| 532 | .comp = options.comp, | 542 | .comp = comp, |
| 533 | .emit = options.emit, | 543 | .emit = options.emit, |
| 534 | .gc_sections = options.gc_sections orelse (output_mode != .Obj), | 544 | .gc_sections = options.gc_sections orelse (output_mode != .Obj), |
| 535 | .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB | 545 | .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB |
| ... | @@ -546,6 +556,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Wasm { | ... | @@ -546,6 +556,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Wasm { |
| 546 | .name = undefined, | 556 | .name = undefined, |
| 547 | .import_table = options.import_table, | 557 | .import_table = options.import_table, |
| 548 | .export_table = options.export_table, | 558 | .export_table = options.export_table, |
| 559 | .import_symbols = options.import_symbols, | ||
| 560 | .export_symbol_names = options.export_symbol_names, | ||
| 561 | .rdynamic = options.rdynamic, | ||
| 562 | .global_base = options.global_base, | ||
| 563 | .initial_memory = options.initial_memory, | ||
| 564 | .max_memory = options.max_memory, | ||
| 565 | .wasi_emulated_libs = options.wasi_emulated_libs, | ||
| 549 | }; | 566 | }; |
| 550 | 567 | ||
| 551 | if (use_llvm) { | 568 | if (use_llvm) { |
| ... | @@ -909,7 +926,10 @@ fn writeI32Const(writer: anytype, val: u32) !void { | ... | @@ -909,7 +926,10 @@ fn writeI32Const(writer: anytype, val: u32) !void { |
| 909 | } | 926 | } |
| 910 | 927 | ||
| 911 | fn setupInitMemoryFunction(wasm: *Wasm) !void { | 928 | fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 912 | const gpa = wasm.base.comp.gpa; | 929 | const comp = wasm.base.comp; |
| 930 | const gpa = comp.gpa; | ||
| 931 | const shared_memory = comp.config.shared_memory; | ||
| 932 | const import_memory = comp.config.import_memory; | ||
| 913 | 933 | ||
| 914 | // Passive segments are used to avoid memory being reinitialized on each | 934 | // Passive segments are used to avoid memory being reinitialized on each |
| 915 | // thread's instantiation. These passive segments are initialized and | 935 | // thread's instantiation. These passive segments are initialized and |
| ... | @@ -920,7 +940,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { | ... | @@ -920,7 +940,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 920 | return; | 940 | return; |
| 921 | } | 941 | } |
| 922 | 942 | ||
| 923 | const flag_address: u32 = if (wasm.base.options.shared_memory) address: { | 943 | const flag_address: u32 = if (shared_memory) address: { |
| 924 | // when we have passive initialization segments and shared memory | 944 | // when we have passive initialization segments and shared memory |
| 925 | // `setupMemory` will create this symbol and set its virtual address. | 945 | // `setupMemory` will create this symbol and set its virtual address. |
| 926 | const loc = wasm.findGlobalSymbol("__wasm_init_memory_flag").?; | 946 | const loc = wasm.findGlobalSymbol("__wasm_init_memory_flag").?; |
| ... | @@ -934,7 +954,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { | ... | @@ -934,7 +954,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 934 | // we have 0 locals | 954 | // we have 0 locals |
| 935 | try leb.writeULEB128(writer, @as(u32, 0)); | 955 | try leb.writeULEB128(writer, @as(u32, 0)); |
| 936 | 956 | ||
| 937 | if (wasm.base.options.shared_memory) { | 957 | if (shared_memory) { |
| 938 | // destination blocks | 958 | // destination blocks |
| 939 | // based on values we jump to corresponding label | 959 | // based on values we jump to corresponding label |
| 940 | try writer.writeByte(std.wasm.opcode(.block)); // $drop | 960 | try writer.writeByte(std.wasm.opcode(.block)); // $drop |
| ... | @@ -968,14 +988,14 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { | ... | @@ -968,14 +988,14 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 968 | var segment_index: u32 = 0; | 988 | var segment_index: u32 = 0; |
| 969 | while (it.next()) |entry| : (segment_index += 1) { | 989 | while (it.next()) |entry| : (segment_index += 1) { |
| 970 | const segment: Segment = wasm.segments.items[entry.value_ptr.*]; | 990 | const segment: Segment = wasm.segments.items[entry.value_ptr.*]; |
| 971 | if (segment.needsPassiveInitialization(wasm.base.options.import_memory, entry.key_ptr.*)) { | 991 | if (segment.needsPassiveInitialization(import_memory, entry.key_ptr.*)) { |
| 972 | // For passive BSS segments we can simple issue a memory.fill(0). | 992 | // For passive BSS segments we can simple issue a memory.fill(0). |
| 973 | // For non-BSS segments we do a memory.init. Both these | 993 | // For non-BSS segments we do a memory.init. Both these |
| 974 | // instructions take as their first argument the destination | 994 | // instructions take as their first argument the destination |
| 975 | // address. | 995 | // address. |
| 976 | try writeI32Const(writer, segment.offset); | 996 | try writeI32Const(writer, segment.offset); |
| 977 | 997 | ||
| 978 | if (wasm.base.options.shared_memory and std.mem.eql(u8, entry.key_ptr.*, ".tdata")) { | 998 | if (shared_memory and std.mem.eql(u8, entry.key_ptr.*, ".tdata")) { |
| 979 | // When we initialize the TLS segment we also set the `__tls_base` | 999 | // When we initialize the TLS segment we also set the `__tls_base` |
| 980 | // global. This allows the runtime to use this static copy of the | 1000 | // global. This allows the runtime to use this static copy of the |
| 981 | // TLS data for the first/main thread. | 1001 | // TLS data for the first/main thread. |
| ... | @@ -1000,7 +1020,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { | ... | @@ -1000,7 +1020,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 1000 | } | 1020 | } |
| 1001 | } | 1021 | } |
| 1002 | 1022 | ||
| 1003 | if (wasm.base.options.shared_memory) { | 1023 | if (shared_memory) { |
| 1004 | // we set the init memory flag to value '2' | 1024 | // we set the init memory flag to value '2' |
| 1005 | try writeI32Const(writer, flag_address); | 1025 | try writeI32Const(writer, flag_address); |
| 1006 | try writeI32Const(writer, 2); | 1026 | try writeI32Const(writer, 2); |
| ... | @@ -1043,12 +1063,12 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { | ... | @@ -1043,12 +1063,12 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 1043 | while (it.next()) |entry| : (segment_index += 1) { | 1063 | while (it.next()) |entry| : (segment_index += 1) { |
| 1044 | const name = entry.key_ptr.*; | 1064 | const name = entry.key_ptr.*; |
| 1045 | const segment: Segment = wasm.segments.items[entry.value_ptr.*]; | 1065 | const segment: Segment = wasm.segments.items[entry.value_ptr.*]; |
| 1046 | if (segment.needsPassiveInitialization(wasm.base.options.import_memory, name) and | 1066 | if (segment.needsPassiveInitialization(import_memory, name) and |
| 1047 | !std.mem.eql(u8, name, ".bss")) | 1067 | !std.mem.eql(u8, name, ".bss")) |
| 1048 | { | 1068 | { |
| 1049 | // The TLS region should not be dropped since its is needed | 1069 | // The TLS region should not be dropped since its is needed |
| 1050 | // during the initialization of each thread (__wasm_init_tls). | 1070 | // during the initialization of each thread (__wasm_init_tls). |
| 1051 | if (wasm.base.options.shared_memory and std.mem.eql(u8, name, ".tdata")) { | 1071 | if (shared_memory and std.mem.eql(u8, name, ".tdata")) { |
| 1052 | continue; | 1072 | continue; |
| 1053 | } | 1073 | } |
| 1054 | 1074 | ||
| ... | @@ -1071,11 +1091,13 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { | ... | @@ -1071,11 +1091,13 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 1071 | /// Constructs a synthetic function that performs runtime relocations for | 1091 | /// Constructs a synthetic function that performs runtime relocations for |
| 1072 | /// TLS symbols. This function is called by `__wasm_init_tls`. | 1092 | /// TLS symbols. This function is called by `__wasm_init_tls`. |
| 1073 | fn setupTLSRelocationsFunction(wasm: *Wasm) !void { | 1093 | fn setupTLSRelocationsFunction(wasm: *Wasm) !void { |
| 1074 | const gpa = wasm.base.comp.gpa; | 1094 | const comp = wasm.base.comp; |
| 1095 | const gpa = comp.gpa; | ||
| 1096 | const shared_memory = comp.config.shared_memory; | ||
| 1075 | 1097 | ||
| 1076 | // When we have TLS GOT entries and shared memory is enabled, | 1098 | // When we have TLS GOT entries and shared memory is enabled, |
| 1077 | // we must perform runtime relocations or else we don't create the function. | 1099 | // we must perform runtime relocations or else we don't create the function. |
| 1078 | if (!wasm.base.options.shared_memory or !wasm.requiresTLSReloc()) { | 1100 | if (!shared_memory or !wasm.requiresTLSReloc()) { |
| 1079 | return; | 1101 | return; |
| 1080 | } | 1102 | } |
| 1081 | 1103 | ||
| ... | @@ -1119,7 +1141,9 @@ fn validateFeatures( | ... | @@ -1119,7 +1141,9 @@ fn validateFeatures( |
| 1119 | to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool, | 1141 | to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool, |
| 1120 | emit_features_count: *u32, | 1142 | emit_features_count: *u32, |
| 1121 | ) !void { | 1143 | ) !void { |
| 1122 | const target = wasm.base.comp.root_mod.resolved_target.result; | 1144 | const comp = wasm.base.comp; |
| 1145 | const target = comp.root_mod.resolved_target.result; | ||
| 1146 | const shared_memory = comp.config.shared_memory; | ||
| 1123 | const cpu_features = target.cpu.features; | 1147 | const cpu_features = target.cpu.features; |
| 1124 | const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects. | 1148 | const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects. |
| 1125 | const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len; | 1149 | const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len; |
| ... | @@ -1190,7 +1214,7 @@ fn validateFeatures( | ... | @@ -1190,7 +1214,7 @@ fn validateFeatures( |
| 1190 | return error.InvalidFeatureSet; | 1214 | return error.InvalidFeatureSet; |
| 1191 | } | 1215 | } |
| 1192 | 1216 | ||
| 1193 | if (wasm.base.options.shared_memory) { | 1217 | if (shared_memory) { |
| 1194 | const disallowed_feature = disallowed[@intFromEnum(types.Feature.Tag.shared_mem)]; | 1218 | const disallowed_feature = disallowed[@intFromEnum(types.Feature.Tag.shared_mem)]; |
| 1195 | if (@as(u1, @truncate(disallowed_feature)) != 0) { | 1219 | if (@as(u1, @truncate(disallowed_feature)) != 0) { |
| 1196 | log.err( | 1220 | log.err( |
| ... | @@ -1255,7 +1279,9 @@ fn validateFeatures( | ... | @@ -1255,7 +1279,9 @@ fn validateFeatures( |
| 1255 | /// if one or multiple undefined references exist. When none exist, the symbol will | 1279 | /// if one or multiple undefined references exist. When none exist, the symbol will |
| 1256 | /// not be created, ensuring we don't unneccesarily emit unreferenced symbols. | 1280 | /// not be created, ensuring we don't unneccesarily emit unreferenced symbols. |
| 1257 | fn resolveLazySymbols(wasm: *Wasm) !void { | 1281 | fn resolveLazySymbols(wasm: *Wasm) !void { |
| 1258 | const gpa = wasm.base.comp.gpa; | 1282 | const comp = wasm.base.comp; |
| 1283 | const gpa = comp.gpa; | ||
| 1284 | const shared_memory = comp.config.shared_memory; | ||
| 1259 | 1285 | ||
| 1260 | if (wasm.string_table.getOffset("__heap_base")) |name_offset| { | 1286 | if (wasm.string_table.getOffset("__heap_base")) |name_offset| { |
| 1261 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { | 1287 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { |
| ... | @@ -1273,7 +1299,7 @@ fn resolveLazySymbols(wasm: *Wasm) !void { | ... | @@ -1273,7 +1299,7 @@ fn resolveLazySymbols(wasm: *Wasm) !void { |
| 1273 | } | 1299 | } |
| 1274 | } | 1300 | } |
| 1275 | 1301 | ||
| 1276 | if (!wasm.base.options.shared_memory) { | 1302 | if (!shared_memory) { |
| 1277 | if (wasm.string_table.getOffset("__tls_base")) |name_offset| { | 1303 | if (wasm.string_table.getOffset("__tls_base")) |name_offset| { |
| 1278 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { | 1304 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { |
| 1279 | const loc = try wasm.createSyntheticSymbolOffset(name_offset, .global); | 1305 | const loc = try wasm.createSyntheticSymbolOffset(name_offset, .global); |
| ... | @@ -1306,8 +1332,9 @@ pub fn findGlobalSymbol(wasm: *Wasm, name: []const u8) ?SymbolLoc { | ... | @@ -1306,8 +1332,9 @@ pub fn findGlobalSymbol(wasm: *Wasm, name: []const u8) ?SymbolLoc { |
| 1306 | } | 1332 | } |
| 1307 | 1333 | ||
| 1308 | fn checkUndefinedSymbols(wasm: *const Wasm) !void { | 1334 | fn checkUndefinedSymbols(wasm: *const Wasm) !void { |
| 1309 | if (wasm.base.comp.config.output_mode == .Obj) return; | 1335 | const comp = wasm.base.comp; |
| 1310 | if (wasm.base.options.import_symbols) return; | 1336 | if (comp.config.output_mode == .Obj) return; |
| 1337 | if (wasm.import_symbols) return; | ||
| 1311 | 1338 | ||
| 1312 | var found_undefined_symbols = false; | 1339 | var found_undefined_symbols = false; |
| 1313 | for (wasm.undefs.values()) |undef| { | 1340 | for (wasm.undefs.values()) |undef| { |
| ... | @@ -2182,7 +2209,10 @@ const Kind = union(enum) { | ... | @@ -2182,7 +2209,10 @@ const Kind = union(enum) { |
| 2182 | 2209 | ||
| 2183 | /// Parses an Atom and inserts its metadata into the corresponding sections. | 2210 | /// Parses an Atom and inserts its metadata into the corresponding sections. |
| 2184 | fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { | 2211 | fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2185 | const gpa = wasm.base.comp.gpa; | 2212 | const comp = wasm.base.comp; |
| 2213 | const gpa = comp.gpa; | ||
| 2214 | const shared_memory = comp.config.shared_memory; | ||
| 2215 | const import_memory = comp.config.import_memory; | ||
| 2186 | const atom = wasm.getAtomPtr(atom_index); | 2216 | const atom = wasm.getAtomPtr(atom_index); |
| 2187 | const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm); | 2217 | const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm); |
| 2188 | const do_garbage_collect = wasm.base.gc_sections; | 2218 | const do_garbage_collect = wasm.base.gc_sections; |
| ... | @@ -2233,7 +2263,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { | ... | @@ -2233,7 +2263,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2233 | // we set the entire region of it to zeroes. | 2263 | // we set the entire region of it to zeroes. |
| 2234 | // We do not have to do this when exporting the memory (the default) because the runtime | 2264 | // We do not have to do this when exporting the memory (the default) because the runtime |
| 2235 | // will do it for us, and we do not emit the bss segment at all. | 2265 | // will do it for us, and we do not emit the bss segment at all. |
| 2236 | if ((wasm.base.comp.config.output_mode == .Obj or wasm.base.options.import_memory) and kind.data == .uninitialized) { | 2266 | if ((wasm.base.comp.config.output_mode == .Obj or import_memory) and kind.data == .uninitialized) { |
| 2237 | @memset(atom.code.items, 0); | 2267 | @memset(atom.code.items, 0); |
| 2238 | } | 2268 | } |
| 2239 | 2269 | ||
| ... | @@ -2250,7 +2280,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { | ... | @@ -2250,7 +2280,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2250 | } else { | 2280 | } else { |
| 2251 | const index: u32 = @intCast(wasm.segments.items.len); | 2281 | const index: u32 = @intCast(wasm.segments.items.len); |
| 2252 | var flags: u32 = 0; | 2282 | var flags: u32 = 0; |
| 2253 | if (wasm.base.options.shared_memory) { | 2283 | if (shared_memory) { |
| 2254 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); | 2284 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); |
| 2255 | } | 2285 | } |
| 2256 | try wasm.segments.append(gpa, .{ | 2286 | try wasm.segments.append(gpa, .{ |
| ... | @@ -2679,9 +2709,11 @@ fn setupStartSection(wasm: *Wasm) !void { | ... | @@ -2679,9 +2709,11 @@ fn setupStartSection(wasm: *Wasm) !void { |
| 2679 | } | 2709 | } |
| 2680 | 2710 | ||
| 2681 | fn initializeTLSFunction(wasm: *Wasm) !void { | 2711 | fn initializeTLSFunction(wasm: *Wasm) !void { |
| 2682 | const gpa = wasm.base.comp.gpa; | 2712 | const comp = wasm.base.comp; |
| 2713 | const gpa = comp.gpa; | ||
| 2714 | const shared_memory = comp.config.shared_memory; | ||
| 2683 | 2715 | ||
| 2684 | if (!wasm.base.options.shared_memory) return; | 2716 | if (!shared_memory) return; |
| 2685 | 2717 | ||
| 2686 | var function_body = std.ArrayList(u8).init(gpa); | 2718 | var function_body = std.ArrayList(u8).init(gpa); |
| 2687 | defer function_body.deinit(); | 2719 | defer function_body.deinit(); |
| ... | @@ -2940,7 +2972,7 @@ fn setupExports(wasm: *Wasm) !void { | ... | @@ -2940,7 +2972,7 @@ fn setupExports(wasm: *Wasm) !void { |
| 2940 | if (wasm.base.comp.config.output_mode == .Obj) return; | 2972 | if (wasm.base.comp.config.output_mode == .Obj) return; |
| 2941 | log.debug("Building exports from symbols", .{}); | 2973 | log.debug("Building exports from symbols", .{}); |
| 2942 | 2974 | ||
| 2943 | const force_exp_names = wasm.base.options.export_symbol_names; | 2975 | const force_exp_names = wasm.export_symbol_names; |
| 2944 | if (force_exp_names.len > 0) { | 2976 | if (force_exp_names.len > 0) { |
| 2945 | var failed_exports = false; | 2977 | var failed_exports = false; |
| 2946 | 2978 | ||
| ... | @@ -2962,7 +2994,7 @@ fn setupExports(wasm: *Wasm) !void { | ... | @@ -2962,7 +2994,7 @@ fn setupExports(wasm: *Wasm) !void { |
| 2962 | 2994 | ||
| 2963 | for (wasm.resolved_symbols.keys()) |sym_loc| { | 2995 | for (wasm.resolved_symbols.keys()) |sym_loc| { |
| 2964 | const symbol = sym_loc.getSymbol(wasm); | 2996 | const symbol = sym_loc.getSymbol(wasm); |
| 2965 | if (!symbol.isExported(wasm.base.options.rdynamic)) continue; | 2997 | if (!symbol.isExported(wasm.rdynamic)) continue; |
| 2966 | 2998 | ||
| 2967 | const sym_name = sym_loc.getName(wasm); | 2999 | const sym_name = sym_loc.getName(wasm); |
| 2968 | const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: { | 3000 | const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: { |
| ... | @@ -2997,8 +3029,9 @@ fn setupExports(wasm: *Wasm) !void { | ... | @@ -2997,8 +3029,9 @@ fn setupExports(wasm: *Wasm) !void { |
| 2997 | } | 3029 | } |
| 2998 | 3030 | ||
| 2999 | fn setupStart(wasm: *Wasm) !void { | 3031 | fn setupStart(wasm: *Wasm) !void { |
| 3032 | const comp = wasm.base.comp; | ||
| 3000 | // do not export entry point if user set none or no default was set. | 3033 | // do not export entry point if user set none or no default was set. |
| 3001 | const entry_name = wasm.base.options.entry orelse return; | 3034 | const entry_name = comp.config.entry orelse return; |
| 3002 | 3035 | ||
| 3003 | const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse { | 3036 | const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse { |
| 3004 | log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name}); | 3037 | log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name}); |
| ... | @@ -3012,13 +3045,15 @@ fn setupStart(wasm: *Wasm) !void { | ... | @@ -3012,13 +3045,15 @@ fn setupStart(wasm: *Wasm) !void { |
| 3012 | } | 3045 | } |
| 3013 | 3046 | ||
| 3014 | // Ensure the symbol is exported so host environment can access it | 3047 | // Ensure the symbol is exported so host environment can access it |
| 3015 | if (wasm.base.comp.config.output_mode != .Obj) { | 3048 | if (comp.config.output_mode != .Obj) { |
| 3016 | symbol.setFlag(.WASM_SYM_EXPORTED); | 3049 | symbol.setFlag(.WASM_SYM_EXPORTED); |
| 3017 | } | 3050 | } |
| 3018 | } | 3051 | } |
| 3019 | 3052 | ||
| 3020 | /// Sets up the memory section of the wasm module, as well as the stack. | 3053 | /// Sets up the memory section of the wasm module, as well as the stack. |
| 3021 | fn setupMemory(wasm: *Wasm) !void { | 3054 | fn setupMemory(wasm: *Wasm) !void { |
| 3055 | const comp = wasm.base.comp; | ||
| 3056 | const shared_memory = comp.config.shared_memory; | ||
| 3022 | log.debug("Setting up memory layout", .{}); | 3057 | log.debug("Setting up memory layout", .{}); |
| 3023 | const page_size = std.wasm.page_size; // 64kb | 3058 | const page_size = std.wasm.page_size; // 64kb |
| 3024 | const stack_alignment: Alignment = .@"16"; // wasm's stack alignment as specified by tool-convention | 3059 | const stack_alignment: Alignment = .@"16"; // wasm's stack alignment as specified by tool-convention |
| ... | @@ -3027,12 +3062,12 @@ fn setupMemory(wasm: *Wasm) !void { | ... | @@ -3027,12 +3062,12 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3027 | // Always place the stack at the start by default | 3062 | // Always place the stack at the start by default |
| 3028 | // unless the user specified the global-base flag | 3063 | // unless the user specified the global-base flag |
| 3029 | var place_stack_first = true; | 3064 | var place_stack_first = true; |
| 3030 | var memory_ptr: u64 = if (wasm.base.options.global_base) |base| blk: { | 3065 | var memory_ptr: u64 = if (wasm.global_base) |base| blk: { |
| 3031 | place_stack_first = false; | 3066 | place_stack_first = false; |
| 3032 | break :blk base; | 3067 | break :blk base; |
| 3033 | } else 0; | 3068 | } else 0; |
| 3034 | 3069 | ||
| 3035 | const is_obj = wasm.base.comp.config.output_mode == .Obj; | 3070 | const is_obj = comp.config.output_mode == .Obj; |
| 3036 | 3071 | ||
| 3037 | if (place_stack_first and !is_obj) { | 3072 | if (place_stack_first and !is_obj) { |
| 3038 | memory_ptr = stack_alignment.forward(memory_ptr); | 3073 | memory_ptr = stack_alignment.forward(memory_ptr); |
| ... | @@ -3059,7 +3094,7 @@ fn setupMemory(wasm: *Wasm) !void { | ... | @@ -3059,7 +3094,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3059 | } | 3094 | } |
| 3060 | if (wasm.findGlobalSymbol("__tls_base")) |loc| { | 3095 | if (wasm.findGlobalSymbol("__tls_base")) |loc| { |
| 3061 | const sym = loc.getSymbol(wasm); | 3096 | const sym = loc.getSymbol(wasm); |
| 3062 | wasm.wasm_globals.items[sym.index - wasm.imported_globals_count].init.i32_const = if (wasm.base.options.shared_memory) | 3097 | wasm.wasm_globals.items[sym.index - wasm.imported_globals_count].init.i32_const = if (shared_memory) |
| 3063 | @as(i32, 0) | 3098 | @as(i32, 0) |
| 3064 | else | 3099 | else |
| 3065 | @as(i32, @intCast(memory_ptr)); | 3100 | @as(i32, @intCast(memory_ptr)); |
| ... | @@ -3072,7 +3107,7 @@ fn setupMemory(wasm: *Wasm) !void { | ... | @@ -3072,7 +3107,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3072 | } | 3107 | } |
| 3073 | 3108 | ||
| 3074 | // create the memory init flag which is used by the init memory function | 3109 | // create the memory init flag which is used by the init memory function |
| 3075 | if (wasm.base.options.shared_memory and wasm.hasPassiveInitializationSegments()) { | 3110 | if (shared_memory and wasm.hasPassiveInitializationSegments()) { |
| 3076 | // align to pointer size | 3111 | // align to pointer size |
| 3077 | memory_ptr = mem.alignForward(u64, memory_ptr, 4); | 3112 | memory_ptr = mem.alignForward(u64, memory_ptr, 4); |
| 3078 | const loc = try wasm.createSyntheticSymbol("__wasm_init_memory_flag", .data); | 3113 | const loc = try wasm.createSyntheticSymbol("__wasm_init_memory_flag", .data); |
| ... | @@ -3098,7 +3133,7 @@ fn setupMemory(wasm: *Wasm) !void { | ... | @@ -3098,7 +3133,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3098 | // For now we only support wasm32 by setting the maximum allowed memory size 2^32-1 | 3133 | // For now we only support wasm32 by setting the maximum allowed memory size 2^32-1 |
| 3099 | const max_memory_allowed: u64 = (1 << 32) - 1; | 3134 | const max_memory_allowed: u64 = (1 << 32) - 1; |
| 3100 | 3135 | ||
| 3101 | if (wasm.base.options.initial_memory) |initial_memory| { | 3136 | if (wasm.initial_memory) |initial_memory| { |
| 3102 | if (!std.mem.isAlignedGeneric(u64, initial_memory, page_size)) { | 3137 | if (!std.mem.isAlignedGeneric(u64, initial_memory, page_size)) { |
| 3103 | log.err("Initial memory must be {d}-byte aligned", .{page_size}); | 3138 | log.err("Initial memory must be {d}-byte aligned", .{page_size}); |
| 3104 | return error.MissAlignment; | 3139 | return error.MissAlignment; |
| ... | @@ -3124,7 +3159,7 @@ fn setupMemory(wasm: *Wasm) !void { | ... | @@ -3124,7 +3159,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3124 | symbol.virtual_address = @as(u32, @intCast(memory_ptr)); | 3159 | symbol.virtual_address = @as(u32, @intCast(memory_ptr)); |
| 3125 | } | 3160 | } |
| 3126 | 3161 | ||
| 3127 | if (wasm.base.options.max_memory) |max_memory| { | 3162 | if (wasm.max_memory) |max_memory| { |
| 3128 | if (!std.mem.isAlignedGeneric(u64, max_memory, page_size)) { | 3163 | if (!std.mem.isAlignedGeneric(u64, max_memory, page_size)) { |
| 3129 | log.err("Maximum memory must be {d}-byte aligned", .{page_size}); | 3164 | log.err("Maximum memory must be {d}-byte aligned", .{page_size}); |
| 3130 | return error.MissAlignment; | 3165 | return error.MissAlignment; |
| ... | @@ -3139,7 +3174,7 @@ fn setupMemory(wasm: *Wasm) !void { | ... | @@ -3139,7 +3174,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3139 | } | 3174 | } |
| 3140 | wasm.memories.limits.max = @as(u32, @intCast(max_memory / page_size)); | 3175 | wasm.memories.limits.max = @as(u32, @intCast(max_memory / page_size)); |
| 3141 | wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_HAS_MAX); | 3176 | wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_HAS_MAX); |
| 3142 | if (wasm.base.options.shared_memory) { | 3177 | if (shared_memory) { |
| 3143 | wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_IS_SHARED); | 3178 | wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_IS_SHARED); |
| 3144 | } | 3179 | } |
| 3145 | log.debug("Maximum memory pages: {?d}", .{wasm.memories.limits.max}); | 3180 | log.debug("Maximum memory pages: {?d}", .{wasm.memories.limits.max}); |
| ... | @@ -3150,20 +3185,22 @@ fn setupMemory(wasm: *Wasm) !void { | ... | @@ -3150,20 +3185,22 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3150 | /// index of the segment within the final data section. When the segment does not yet | 3185 | /// index of the segment within the final data section. When the segment does not yet |
| 3151 | /// exist, a new one will be initialized and appended. The new index will be returned in that case. | 3186 | /// exist, a new one will be initialized and appended. The new index will be returned in that case. |
| 3152 | pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u32 { | 3187 | pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u32 { |
| 3153 | const gpa = wasm.base.comp.gpa; | 3188 | const comp = wasm.base.comp; |
| 3189 | const gpa = comp.gpa; | ||
| 3154 | const object: Object = wasm.objects.items[object_index]; | 3190 | const object: Object = wasm.objects.items[object_index]; |
| 3155 | const symbol = object.symtable[symbol_index]; | 3191 | const symbol = object.symtable[symbol_index]; |
| 3156 | const index: u32 = @intCast(wasm.segments.items.len); | 3192 | const index: u32 = @intCast(wasm.segments.items.len); |
| 3193 | const shared_memory = comp.config.shared_memory; | ||
| 3157 | 3194 | ||
| 3158 | switch (symbol.tag) { | 3195 | switch (symbol.tag) { |
| 3159 | .data => { | 3196 | .data => { |
| 3160 | const segment_info = object.segment_info[symbol.index]; | 3197 | const segment_info = object.segment_info[symbol.index]; |
| 3161 | const merge_segment = wasm.base.comp.config.output_mode != .Obj; | 3198 | const merge_segment = comp.config.output_mode != .Obj; |
| 3162 | const result = try wasm.data_segments.getOrPut(gpa, segment_info.outputName(merge_segment)); | 3199 | const result = try wasm.data_segments.getOrPut(gpa, segment_info.outputName(merge_segment)); |
| 3163 | if (!result.found_existing) { | 3200 | if (!result.found_existing) { |
| 3164 | result.value_ptr.* = index; | 3201 | result.value_ptr.* = index; |
| 3165 | var flags: u32 = 0; | 3202 | var flags: u32 = 0; |
| 3166 | if (wasm.base.options.shared_memory) { | 3203 | if (shared_memory) { |
| 3167 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); | 3204 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); |
| 3168 | } | 3205 | } |
| 3169 | try wasm.segments.append(gpa, .{ | 3206 | try wasm.segments.append(gpa, .{ |
| ... | @@ -3445,6 +3482,8 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -3445,6 +3482,8 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3445 | defer tracy.end(); | 3482 | defer tracy.end(); |
| 3446 | 3483 | ||
| 3447 | const gpa = wasm.base.comp.gpa; | 3484 | const gpa = wasm.base.comp.gpa; |
| 3485 | const shared_memory = comp.config.shared_memory; | ||
| 3486 | const import_memory = comp.config.import_memory; | ||
| 3448 | 3487 | ||
| 3449 | // Used for all temporary memory allocated during flushin | 3488 | // Used for all temporary memory allocated during flushin |
| 3450 | var arena_instance = std.heap.ArenaAllocator.init(gpa); | 3489 | var arena_instance = std.heap.ArenaAllocator.init(gpa); |
| ... | @@ -3509,8 +3548,8 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -3509,8 +3548,8 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3509 | man.hash.addOptionalBytes(wasm.base.comp.config.entry); | 3548 | man.hash.addOptionalBytes(wasm.base.comp.config.entry); |
| 3510 | man.hash.add(wasm.base.stack_size); | 3549 | man.hash.add(wasm.base.stack_size); |
| 3511 | man.hash.add(wasm.base.build_id); | 3550 | man.hash.add(wasm.base.build_id); |
| 3512 | man.hash.add(wasm.base.comp.config.import_memory); | 3551 | man.hash.add(import_memory); |
| 3513 | man.hash.add(wasm.base.comp.config.shared_memory); | 3552 | man.hash.add(shared_memory); |
| 3514 | man.hash.add(wasm.import_table); | 3553 | man.hash.add(wasm.import_table); |
| 3515 | man.hash.add(wasm.export_table); | 3554 | man.hash.add(wasm.export_table); |
| 3516 | man.hash.addOptional(wasm.initial_memory); | 3555 | man.hash.addOptional(wasm.initial_memory); |
| ... | @@ -3726,8 +3765,12 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -3726,8 +3765,12 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3726 | } else if (Value.fromInterned(variable.init).isUndefDeep(mod)) { | 3765 | } else if (Value.fromInterned(variable.init).isUndefDeep(mod)) { |
| 3727 | // for safe build modes, we store the atom in the data segment, | 3766 | // for safe build modes, we store the atom in the data segment, |
| 3728 | // whereas for unsafe build modes we store it in bss. | 3767 | // whereas for unsafe build modes we store it in bss. |
| 3729 | const is_initialized = wasm.base.options.optimize_mode == .Debug or | 3768 | const decl_namespace = mod.namespacePtr(decl.src_namespace); |
| 3730 | wasm.base.options.optimize_mode == .ReleaseSafe; | 3769 | const optimize_mode = decl_namespace.file_scope.mod.optimize_mode; |
| 3770 | const is_initialized = switch (optimize_mode) { | ||
| 3771 | .Debug, .ReleaseSafe => true, | ||
| 3772 | .ReleaseFast, .ReleaseSmall => false, | ||
| 3773 | }; | ||
| 3731 | try wasm.parseAtom(atom_index, .{ .data = if (is_initialized) .initialized else .uninitialized }); | 3774 | try wasm.parseAtom(atom_index, .{ .data = if (is_initialized) .initialized else .uninitialized }); |
| 3732 | } else { | 3775 | } else { |
| 3733 | // when the decl is all zeroes, we store the atom in the bss segment, | 3776 | // when the decl is all zeroes, we store the atom in the bss segment, |
| ... | @@ -3788,9 +3831,13 @@ fn writeToFile( | ... | @@ -3788,9 +3831,13 @@ fn writeToFile( |
| 3788 | feature_count: u32, | 3831 | feature_count: u32, |
| 3789 | arena: Allocator, | 3832 | arena: Allocator, |
| 3790 | ) !void { | 3833 | ) !void { |
| 3791 | const gpa = wasm.base.comp.gpa; | 3834 | const comp = wasm.base.comp; |
| 3792 | const use_llvm = wasm.base.comp.config.use_llvm; | 3835 | const gpa = comp.gpa; |
| 3793 | const use_lld = build_options.have_llvm and wasm.base.comp.config.use_lld; | 3836 | const use_llvm = comp.config.use_llvm; |
| 3837 | const use_lld = build_options.have_llvm and comp.config.use_lld; | ||
| 3838 | const shared_memory = comp.config.shared_memory; | ||
| 3839 | const import_memory = comp.config.import_memory; | ||
| 3840 | const export_memory = comp.config.export_memory; | ||
| 3794 | 3841 | ||
| 3795 | // Size of each section header | 3842 | // Size of each section header |
| 3796 | const header_size = 5 + 1; | 3843 | const header_size = 5 + 1; |
| ... | @@ -3800,7 +3847,7 @@ fn writeToFile( | ... | @@ -3800,7 +3847,7 @@ fn writeToFile( |
| 3800 | var code_section_index: ?u32 = null; | 3847 | var code_section_index: ?u32 = null; |
| 3801 | // Index of the data section. Used to tell relocation table where the section lives. | 3848 | // Index of the data section. Used to tell relocation table where the section lives. |
| 3802 | var data_section_index: ?u32 = null; | 3849 | var data_section_index: ?u32 = null; |
| 3803 | const is_obj = wasm.base.comp.config.output_mode == .Obj or (!use_llvm and use_lld); | 3850 | const is_obj = comp.config.output_mode == .Obj or (!use_llvm and use_lld); |
| 3804 | 3851 | ||
| 3805 | var binary_bytes = std.ArrayList(u8).init(gpa); | 3852 | var binary_bytes = std.ArrayList(u8).init(gpa); |
| 3806 | defer binary_bytes.deinit(); | 3853 | defer binary_bytes.deinit(); |
| ... | @@ -3840,8 +3887,6 @@ fn writeToFile( | ... | @@ -3840,8 +3887,6 @@ fn writeToFile( |
| 3840 | } | 3887 | } |
| 3841 | 3888 | ||
| 3842 | // Import section | 3889 | // Import section |
| 3843 | const import_memory = wasm.base.options.import_memory or is_obj; | ||
| 3844 | const export_memory = wasm.base.options.export_memory; | ||
| 3845 | if (wasm.imports.count() != 0 or import_memory) { | 3890 | if (wasm.imports.count() != 0 or import_memory) { |
| 3846 | const header_offset = try reserveVecSectionHeader(&binary_bytes); | 3891 | const header_offset = try reserveVecSectionHeader(&binary_bytes); |
| 3847 | 3892 | ||
| ... | @@ -4018,7 +4063,7 @@ fn writeToFile( | ... | @@ -4018,7 +4063,7 @@ fn writeToFile( |
| 4018 | 4063 | ||
| 4019 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. | 4064 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. |
| 4020 | const data_segments_count = wasm.data_segments.count() - @intFromBool(wasm.data_segments.contains(".bss") and !import_memory); | 4065 | const data_segments_count = wasm.data_segments.count() - @intFromBool(wasm.data_segments.contains(".bss") and !import_memory); |
| 4021 | if (data_segments_count != 0 and wasm.base.options.shared_memory) { | 4066 | if (data_segments_count != 0 and shared_memory) { |
| 4022 | const header_offset = try reserveVecSectionHeader(&binary_bytes); | 4067 | const header_offset = try reserveVecSectionHeader(&binary_bytes); |
| 4023 | try writeVecSectionHeader( | 4068 | try writeVecSectionHeader( |
| 4024 | binary_bytes.items, | 4069 | binary_bytes.items, |
| ... | @@ -4160,11 +4205,11 @@ fn writeToFile( | ... | @@ -4160,11 +4205,11 @@ fn writeToFile( |
| 4160 | if (data_section_index) |data_index| { | 4205 | if (data_section_index) |data_index| { |
| 4161 | try wasm.emitDataRelocations(&binary_bytes, data_index, symbol_table); | 4206 | try wasm.emitDataRelocations(&binary_bytes, data_index, symbol_table); |
| 4162 | } | 4207 | } |
| 4163 | } else if (!wasm.base.options.strip) { | 4208 | } else if (wasm.base.debug_format != .strip) { |
| 4164 | try wasm.emitNameSection(&binary_bytes, arena); | 4209 | try wasm.emitNameSection(&binary_bytes, arena); |
| 4165 | } | 4210 | } |
| 4166 | 4211 | ||
| 4167 | if (!wasm.base.options.strip) { | 4212 | if (wasm.base.debug_format != .strip) { |
| 4168 | // The build id must be computed on the main sections only, | 4213 | // The build id must be computed on the main sections only, |
| 4169 | // so we have to do it now, before the debug sections. | 4214 | // so we have to do it now, before the debug sections. |
| 4170 | switch (wasm.base.build_id) { | 4215 | switch (wasm.base.build_id) { |
| ... | @@ -4193,7 +4238,7 @@ fn writeToFile( | ... | @@ -4193,7 +4238,7 @@ fn writeToFile( |
| 4193 | } | 4238 | } |
| 4194 | 4239 | ||
| 4195 | // if (wasm.dwarf) |*dwarf| { | 4240 | // if (wasm.dwarf) |*dwarf| { |
| 4196 | // const mod = wasm.base.comp.module.?; | 4241 | // const mod = comp.module.?; |
| 4197 | // try dwarf.writeDbgAbbrev(); | 4242 | // try dwarf.writeDbgAbbrev(); |
| 4198 | // // for debug info and ranges, the address is always 0, | 4243 | // // for debug info and ranges, the address is always 0, |
| 4199 | // // as locations are always offsets relative to 'code' section. | 4244 | // // as locations are always offsets relative to 'code' section. |
| ... | @@ -4380,6 +4425,8 @@ fn emitFeaturesSection(binary_bytes: *std.ArrayList(u8), enabled_features: []con | ... | @@ -4380,6 +4425,8 @@ fn emitFeaturesSection(binary_bytes: *std.ArrayList(u8), enabled_features: []con |
| 4380 | } | 4425 | } |
| 4381 | 4426 | ||
| 4382 | fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem.Allocator) !void { | 4427 | fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem.Allocator) !void { |
| 4428 | const comp = wasm.base.comp; | ||
| 4429 | const import_memory = comp.config.import_memory; | ||
| 4383 | const Name = struct { | 4430 | const Name = struct { |
| 4384 | index: u32, | 4431 | index: u32, |
| 4385 | name: []const u8, | 4432 | name: []const u8, |
| ... | @@ -4418,7 +4465,7 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem | ... | @@ -4418,7 +4465,7 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem |
| 4418 | for (wasm.data_segments.keys()) |key| { | 4465 | for (wasm.data_segments.keys()) |key| { |
| 4419 | // bss section is not emitted when this condition holds true, so we also | 4466 | // bss section is not emitted when this condition holds true, so we also |
| 4420 | // do not output a name for it. | 4467 | // do not output a name for it. |
| 4421 | if (!wasm.base.options.import_memory and std.mem.eql(u8, key, ".bss")) continue; | 4468 | if (!import_memory and std.mem.eql(u8, key, ".bss")) continue; |
| 4422 | segments.appendAssumeCapacity(.{ .index = data_segment_index, .name = key }); | 4469 | segments.appendAssumeCapacity(.{ .index = data_segment_index, .name = key }); |
| 4423 | data_segment_index += 1; | 4470 | data_segment_index += 1; |
| 4424 | } | 4471 | } |
| ... | @@ -4528,6 +4575,11 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4528,6 +4575,11 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4528 | const tracy = trace(@src()); | 4575 | const tracy = trace(@src()); |
| 4529 | defer tracy.end(); | 4576 | defer tracy.end(); |
| 4530 | 4577 | ||
| 4578 | const shared_memory = comp.config.shared_memory; | ||
| 4579 | const export_memory = comp.config.export_memory; | ||
| 4580 | const import_memory = comp.config.import_memory; | ||
| 4581 | const target = comp.root_mod.resolved_target.result; | ||
| 4582 | |||
| 4531 | const gpa = wasm.base.comp.gpa; | 4583 | const gpa = wasm.base.comp.gpa; |
| 4532 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); | 4584 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| 4533 | defer arena_allocator.deinit(); | 4585 | defer arena_allocator.deinit(); |
| ... | @@ -4560,8 +4612,6 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4560,8 +4612,6 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4560 | break :blk null; | 4612 | break :blk null; |
| 4561 | }; | 4613 | }; |
| 4562 | 4614 | ||
| 4563 | const target = wasm.base.comp.root_mod.resolved_target.result; | ||
| 4564 | |||
| 4565 | const id_symlink_basename = "lld.id"; | 4615 | const id_symlink_basename = "lld.id"; |
| 4566 | 4616 | ||
| 4567 | var man: Cache.Manifest = undefined; | 4617 | var man: Cache.Manifest = undefined; |
| ... | @@ -4577,7 +4627,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4577,7 +4627,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4577 | 4627 | ||
| 4578 | comptime assert(Compilation.link_hash_implementation_version == 10); | 4628 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 4579 | 4629 | ||
| 4580 | for (wasm.base.options.objects) |obj| { | 4630 | for (comp.objects) |obj| { |
| 4581 | _ = try man.addFile(obj.path, null); | 4631 | _ = try man.addFile(obj.path, null); |
| 4582 | man.hash.add(obj.must_link); | 4632 | man.hash.add(obj.must_link); |
| 4583 | } | 4633 | } |
| ... | @@ -4589,17 +4639,17 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4589,17 +4639,17 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4589 | man.hash.addOptionalBytes(wasm.base.comp.config.entry); | 4639 | man.hash.addOptionalBytes(wasm.base.comp.config.entry); |
| 4590 | man.hash.add(wasm.base.stack_size); | 4640 | man.hash.add(wasm.base.stack_size); |
| 4591 | man.hash.add(wasm.base.build_id); | 4641 | man.hash.add(wasm.base.build_id); |
| 4592 | man.hash.add(wasm.base.options.import_memory); | 4642 | man.hash.add(import_memory); |
| 4593 | man.hash.add(wasm.base.options.export_memory); | 4643 | man.hash.add(export_memory); |
| 4594 | man.hash.add(wasm.import_table); | 4644 | man.hash.add(wasm.import_table); |
| 4595 | man.hash.add(wasm.export_table); | 4645 | man.hash.add(wasm.export_table); |
| 4596 | man.hash.addOptional(wasm.base.options.initial_memory); | 4646 | man.hash.addOptional(wasm.initial_memory); |
| 4597 | man.hash.addOptional(wasm.base.options.max_memory); | 4647 | man.hash.addOptional(wasm.max_memory); |
| 4598 | man.hash.add(wasm.base.options.shared_memory); | 4648 | man.hash.add(shared_memory); |
| 4599 | man.hash.addOptional(wasm.base.options.global_base); | 4649 | man.hash.addOptional(wasm.global_base); |
| 4600 | man.hash.add(wasm.base.options.export_symbol_names.len); | 4650 | man.hash.add(wasm.export_symbol_names.len); |
| 4601 | // strip does not need to go into the linker hash because it is part of the hash namespace | 4651 | // strip does not need to go into the linker hash because it is part of the hash namespace |
| 4602 | for (wasm.base.options.export_symbol_names) |symbol_name| { | 4652 | for (wasm.export_symbol_names) |symbol_name| { |
| 4603 | man.hash.addBytes(symbol_name); | 4653 | man.hash.addBytes(symbol_name); |
| 4604 | } | 4654 | } |
| 4605 | 4655 | ||
| ... | @@ -4637,8 +4687,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4637,8 +4687,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4637 | // here. TODO: think carefully about how we can avoid this redundant operation when doing | 4687 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 4638 | // build-obj. See also the corresponding TODO in linkAsArchive. | 4688 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 4639 | const the_object_path = blk: { | 4689 | const the_object_path = blk: { |
| 4640 | if (wasm.base.options.objects.len != 0) | 4690 | if (comp.objects.len != 0) |
| 4641 | break :blk wasm.base.options.objects[0].path; | 4691 | break :blk comp.objects[0].path; |
| 4642 | 4692 | ||
| 4643 | if (comp.c_object_table.count() != 0) | 4693 | if (comp.c_object_table.count() != 0) |
| 4644 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 4694 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -4666,19 +4716,19 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4666,19 +4716,19 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4666 | try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command }); | 4716 | try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command }); |
| 4667 | try argv.append("--error-limit=0"); | 4717 | try argv.append("--error-limit=0"); |
| 4668 | 4718 | ||
| 4669 | if (wasm.base.options.lto) { | 4719 | if (comp.config.lto) { |
| 4670 | switch (wasm.base.options.optimize_mode) { | 4720 | switch (comp.root_mod.optimize_mode) { |
| 4671 | .Debug => {}, | 4721 | .Debug => {}, |
| 4672 | .ReleaseSmall => try argv.append("-O2"), | 4722 | .ReleaseSmall => try argv.append("-O2"), |
| 4673 | .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), | 4723 | .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), |
| 4674 | } | 4724 | } |
| 4675 | } | 4725 | } |
| 4676 | 4726 | ||
| 4677 | if (wasm.base.options.import_memory) { | 4727 | if (import_memory) { |
| 4678 | try argv.append("--import-memory"); | 4728 | try argv.append("--import-memory"); |
| 4679 | } | 4729 | } |
| 4680 | 4730 | ||
| 4681 | if (wasm.base.options.export_memory) { | 4731 | if (export_memory) { |
| 4682 | try argv.append("--export-memory"); | 4732 | try argv.append("--export-memory"); |
| 4683 | } | 4733 | } |
| 4684 | 4734 | ||
| ... | @@ -4698,25 +4748,25 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4698,25 +4748,25 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4698 | try argv.append("--no-gc-sections"); | 4748 | try argv.append("--no-gc-sections"); |
| 4699 | } | 4749 | } |
| 4700 | 4750 | ||
| 4701 | if (wasm.base.options.strip) { | 4751 | if (wasm.base.debug_format == .strip) { |
| 4702 | try argv.append("-s"); | 4752 | try argv.append("-s"); |
| 4703 | } | 4753 | } |
| 4704 | 4754 | ||
| 4705 | if (wasm.base.options.initial_memory) |initial_memory| { | 4755 | if (wasm.initial_memory) |initial_memory| { |
| 4706 | const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory}); | 4756 | const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory}); |
| 4707 | try argv.append(arg); | 4757 | try argv.append(arg); |
| 4708 | } | 4758 | } |
| 4709 | 4759 | ||
| 4710 | if (wasm.base.options.max_memory) |max_memory| { | 4760 | if (wasm.max_memory) |max_memory| { |
| 4711 | const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory}); | 4761 | const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory}); |
| 4712 | try argv.append(arg); | 4762 | try argv.append(arg); |
| 4713 | } | 4763 | } |
| 4714 | 4764 | ||
| 4715 | if (wasm.base.options.shared_memory) { | 4765 | if (shared_memory) { |
| 4716 | try argv.append("--shared-memory"); | 4766 | try argv.append("--shared-memory"); |
| 4717 | } | 4767 | } |
| 4718 | 4768 | ||
| 4719 | if (wasm.base.options.global_base) |global_base| { | 4769 | if (wasm.global_base) |global_base| { |
| 4720 | const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base}); | 4770 | const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base}); |
| 4721 | try argv.append(arg); | 4771 | try argv.append(arg); |
| 4722 | } else { | 4772 | } else { |
| ... | @@ -4728,16 +4778,16 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4728,16 +4778,16 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4728 | } | 4778 | } |
| 4729 | 4779 | ||
| 4730 | // Users are allowed to specify which symbols they want to export to the wasm host. | 4780 | // Users are allowed to specify which symbols they want to export to the wasm host. |
| 4731 | for (wasm.base.options.export_symbol_names) |symbol_name| { | 4781 | for (wasm.export_symbol_names) |symbol_name| { |
| 4732 | const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name}); | 4782 | const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name}); |
| 4733 | try argv.append(arg); | 4783 | try argv.append(arg); |
| 4734 | } | 4784 | } |
| 4735 | 4785 | ||
| 4736 | if (wasm.base.options.rdynamic) { | 4786 | if (wasm.rdynamic) { |
| 4737 | try argv.append("--export-dynamic"); | 4787 | try argv.append("--export-dynamic"); |
| 4738 | } | 4788 | } |
| 4739 | 4789 | ||
| 4740 | if (wasm.base.options.entry) |entry| { | 4790 | if (comp.config.entry) |entry| { |
| 4741 | try argv.append("--entry"); | 4791 | try argv.append("--entry"); |
| 4742 | try argv.append(entry); | 4792 | try argv.append(entry); |
| 4743 | } else { | 4793 | } else { |
| ... | @@ -4749,14 +4799,14 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4749,14 +4799,14 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4749 | try std.fmt.allocPrint(arena, "stack-size={d}", .{wasm.base.stack_size}), | 4799 | try std.fmt.allocPrint(arena, "stack-size={d}", .{wasm.base.stack_size}), |
| 4750 | }); | 4800 | }); |
| 4751 | 4801 | ||
| 4752 | if (wasm.base.options.import_symbols) { | 4802 | if (wasm.import_symbols) { |
| 4753 | try argv.append("--allow-undefined"); | 4803 | try argv.append("--allow-undefined"); |
| 4754 | } | 4804 | } |
| 4755 | 4805 | ||
| 4756 | if (wasm.base.comp.config.output_mode == .Lib and wasm.base.comp.config.link_mode == .Dynamic) { | 4806 | if (wasm.base.comp.config.output_mode == .Lib and wasm.base.comp.config.link_mode == .Dynamic) { |
| 4757 | try argv.append("--shared"); | 4807 | try argv.append("--shared"); |
| 4758 | } | 4808 | } |
| 4759 | if (wasm.base.options.pie) { | 4809 | if (comp.config.pie) { |
| 4760 | try argv.append("--pie"); | 4810 | try argv.append("--pie"); |
| 4761 | } | 4811 | } |
| 4762 | 4812 | ||
| ... | @@ -4782,15 +4832,15 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4782,15 +4832,15 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4782 | )); | 4832 | )); |
| 4783 | } | 4833 | } |
| 4784 | 4834 | ||
| 4785 | if (wasm.base.options.link_libc) { | 4835 | if (comp.config.link_libc) { |
| 4786 | try argv.append(try comp.get_libc_crt_file( | 4836 | try argv.append(try comp.get_libc_crt_file( |
| 4787 | arena, | 4837 | arena, |
| 4788 | wasi_libc.execModelCrtFileFullName(wasm.base.options.wasi_exec_model), | 4838 | wasi_libc.execModelCrtFileFullName(comp.config.wasi_exec_model), |
| 4789 | )); | 4839 | )); |
| 4790 | try argv.append(try comp.get_libc_crt_file(arena, "libc.a")); | 4840 | try argv.append(try comp.get_libc_crt_file(arena, "libc.a")); |
| 4791 | } | 4841 | } |
| 4792 | 4842 | ||
| 4793 | if (wasm.base.options.link_libcpp) { | 4843 | if (comp.config.link_libcpp) { |
| 4794 | try argv.append(comp.libcxx_static_lib.?.full_object_path); | 4844 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 4795 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); | 4845 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 4796 | } | 4846 | } |
| ... | @@ -4799,7 +4849,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4799,7 +4849,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4799 | 4849 | ||
| 4800 | // Positional arguments to the linker such as object files. | 4850 | // Positional arguments to the linker such as object files. |
| 4801 | var whole_archive = false; | 4851 | var whole_archive = false; |
| 4802 | for (wasm.base.options.objects) |obj| { | 4852 | for (comp.objects) |obj| { |
| 4803 | if (obj.must_link and !whole_archive) { | 4853 | if (obj.must_link and !whole_archive) { |
| 4804 | try argv.append("-whole-archive"); | 4854 | try argv.append("-whole-archive"); |
| 4805 | whole_archive = true; | 4855 | whole_archive = true; |
| ... | @@ -4822,8 +4872,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4822,8 +4872,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4822 | } | 4872 | } |
| 4823 | 4873 | ||
| 4824 | if (wasm.base.comp.config.output_mode != .Obj and | 4874 | if (wasm.base.comp.config.output_mode != .Obj and |
| 4825 | !wasm.base.options.skip_linker_dependencies and | 4875 | !comp.skip_linker_dependencies and |
| 4826 | !wasm.base.options.link_libc) | 4876 | !comp.config.link_libc) |
| 4827 | { | 4877 | { |
| 4828 | try argv.append(comp.libc_static_lib.?.full_object_path); | 4878 | try argv.append(comp.libc_static_lib.?.full_object_path); |
| 4829 | } | 4879 | } |
| ... | @@ -5168,10 +5218,13 @@ fn emitDataRelocations( | ... | @@ -5168,10 +5218,13 @@ fn emitDataRelocations( |
| 5168 | } | 5218 | } |
| 5169 | 5219 | ||
| 5170 | fn hasPassiveInitializationSegments(wasm: *const Wasm) bool { | 5220 | fn hasPassiveInitializationSegments(wasm: *const Wasm) bool { |
| 5221 | const comp = wasm.base.comp; | ||
| 5222 | const import_memory = comp.config.import_memory; | ||
| 5223 | |||
| 5171 | var it = wasm.data_segments.iterator(); | 5224 | var it = wasm.data_segments.iterator(); |
| 5172 | while (it.next()) |entry| { | 5225 | while (it.next()) |entry| { |
| 5173 | const segment: Segment = wasm.segments.items[entry.value_ptr.*]; | 5226 | const segment: Segment = wasm.segments.items[entry.value_ptr.*]; |
| 5174 | if (segment.needsPassiveInitialization(wasm.base.options.import_memory, entry.key_ptr.*)) { | 5227 | if (segment.needsPassiveInitialization(import_memory, entry.key_ptr.*)) { |
| 5175 | return true; | 5228 | return true; |
| 5176 | } | 5229 | } |
| 5177 | } | 5230 | } |
| ... | @@ -5227,14 +5280,14 @@ fn markReferences(wasm: *Wasm) !void { | ... | @@ -5227,14 +5280,14 @@ fn markReferences(wasm: *Wasm) !void { |
| 5227 | 5280 | ||
| 5228 | for (wasm.resolved_symbols.keys()) |sym_loc| { | 5281 | for (wasm.resolved_symbols.keys()) |sym_loc| { |
| 5229 | const sym = sym_loc.getSymbol(wasm); | 5282 | const sym = sym_loc.getSymbol(wasm); |
| 5230 | if (sym.isExported(wasm.base.options.rdynamic) or sym.isNoStrip() or !do_garbage_collect) { | 5283 | if (sym.isExported(wasm.rdynamic) or sym.isNoStrip() or !do_garbage_collect) { |
| 5231 | try wasm.mark(sym_loc); | 5284 | try wasm.mark(sym_loc); |
| 5232 | continue; | 5285 | continue; |
| 5233 | } | 5286 | } |
| 5234 | 5287 | ||
| 5235 | // Debug sections may require to be parsed and marked when it contains | 5288 | // Debug sections may require to be parsed and marked when it contains |
| 5236 | // relocations to alive symbols. | 5289 | // relocations to alive symbols. |
| 5237 | if (sym.tag == .section and !wasm.base.options.strip) { | 5290 | if (sym.tag == .section and wasm.base.debug_format != .strip) { |
| 5238 | const file = sym_loc.file orelse continue; // Incremental debug info is done independently | 5291 | const file = sym_loc.file orelse continue; // Incremental debug info is done independently |
| 5239 | const object = &wasm.objects.items[file]; | 5292 | const object = &wasm.objects.items[file]; |
| 5240 | const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm); | 5293 | const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm); |