From ef24f2dd93729493531c427aaac54444597f6e66 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 28 Feb 2020 02:36:16 -0500 Subject: remove special darwin os version min handling now it is integrated with zig's target OS range. --- src/link.cpp | 127 ++++++++--------------------------------------------------- 1 file changed, 17 insertions(+), 110 deletions(-) (limited to 'src/link.cpp') diff --git a/src/link.cpp b/src/link.cpp index 901390feae..588771d8bf 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -2371,99 +2371,6 @@ static void construct_linker_job_coff(LinkJob *lj) { } } - -// Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the -// grouped values as integers. Numbers which are not provided are set to 0. -// return true if the entire string was parsed (9.2), or all groups were -// parsed (10.3.5extrastuff). -static bool darwin_get_release_version(const char *str, int *major, int *minor, int *micro, bool *had_extra) { - *had_extra = false; - - *major = 0; - *minor = 0; - *micro = 0; - - if (*str == '\0') - return false; - - char *end; - *major = (int)strtol(str, &end, 10); - if (*str != '\0' && *end == '\0') - return true; - if (*end != '.') - return false; - - str = end + 1; - *minor = (int)strtol(str, &end, 10); - if (*str != '\0' && *end == '\0') - return true; - if (*end != '.') - return false; - - str = end + 1; - *micro = (int)strtol(str, &end, 10); - if (*str != '\0' && *end == '\0') - return true; - if (str == end) - return false; - *had_extra = true; - return true; -} - -enum DarwinPlatformKind { - MacOS, - IPhoneOS, - IPhoneOSSimulator, -}; - -struct DarwinPlatform { - DarwinPlatformKind kind; - int major; - int minor; - int micro; -}; - -static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { - CodeGen *g = lj->codegen; - - if (g->mmacosx_version_min) { - platform->kind = MacOS; - } else if (g->mios_version_min) { - platform->kind = IPhoneOS; - } else if (g->zig_target->os == OsMacOSX) { - platform->kind = MacOS; - g->mmacosx_version_min = buf_create_from_str("10.14"); - } else { - zig_panic("unable to infer -mmacosx-version-min or -mios-version-min"); - } - - bool had_extra; - if (platform->kind == MacOS) { - if (!darwin_get_release_version(buf_ptr(g->mmacosx_version_min), - &platform->major, &platform->minor, &platform->micro, &had_extra) || - had_extra || platform->major != 10 || platform->minor >= 100 || platform->micro >= 100) - { - zig_panic("invalid -mmacosx-version-min"); - } - } else if (platform->kind == IPhoneOS) { - if (!darwin_get_release_version(buf_ptr(g->mios_version_min), - &platform->major, &platform->minor, &platform->micro, &had_extra) || - had_extra || platform->major >= 10 || platform->minor >= 100 || platform->micro >= 100) - { - zig_panic("invalid -mios-version-min"); - } - } else { - zig_unreachable(); - } - - if (platform->kind == IPhoneOS && - (g->zig_target->arch == ZigLLVM_x86 || - g->zig_target->arch == ZigLLVM_x86_64)) - { - platform->kind = IPhoneOSSimulator; - } -} - static void construct_linker_job_macho(LinkJob *lj) { CodeGen *g = lj->codegen; @@ -2507,25 +2414,25 @@ static void construct_linker_job_macho(LinkJob *lj) { lj->args.append("-arch"); lj->args.append(get_darwin_arch_string(g->zig_target)); - DarwinPlatform platform; - get_darwin_platform(lj, &platform); - switch (platform.kind) { - case MacOS: + if (g->zig_target->glibc_or_darwin_version != nullptr) { + if (g->zig_target->os == OsMacOSX) { lj->args.append("-macosx_version_min"); - break; - case IPhoneOS: - lj->args.append("-iphoneos_version_min"); - break; - case IPhoneOSSimulator: - lj->args.append("-ios_simulator_version_min"); - break; - } - Buf *version_string = buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro); - lj->args.append(buf_ptr(version_string)); - - lj->args.append("-sdk_version"); - lj->args.append(buf_ptr(version_string)); + } else if (g->zig_target->os == OsIOS) { + if (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64) { + lj->args.append("-ios_simulator_version_min"); + } else { + lj->args.append("-iphoneos_version_min"); + } + } + Buf *version_string = buf_sprintf("%d.%d.%d", + g->zig_target->glibc_or_darwin_version->major, + g->zig_target->glibc_or_darwin_version->minor, + g->zig_target->glibc_or_darwin_version->patch); + lj->args.append(buf_ptr(version_string)); + lj->args.append("-sdk_version"); + lj->args.append(buf_ptr(version_string)); + } if (g->out_type == OutTypeExe) { lj->args.append("-pie"); -- cgit v1.2.3 From 500dde32d5cf59f5700fb3f69ae6c7a0defd8a93 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 28 Feb 2020 13:27:52 -0500 Subject: dynamic_linker becomes a field of std.zig.CrossTarget --- lib/std/build.zig | 12 +++--- lib/std/target.zig | 92 ++++++++++++++++++++++++++++++-------------- lib/std/zig/cross_target.zig | 17 ++++++-- lib/std/zig/system.zig | 77 ++++++++++++------------------------ src-self-hosted/stage2.zig | 15 ++++---- src/all_types.hpp | 1 - src/codegen.cpp | 19 ++------- src/link.cpp | 4 +- src/main.cpp | 11 +++--- src/stage2.cpp | 7 +++- src/stage2.h | 3 +- src/target.cpp | 4 +- src/target.hpp | 2 +- 13 files changed, 137 insertions(+), 127 deletions(-) (limited to 'src/link.cpp') diff --git a/lib/std/build.zig b/lib/std/build.zig index 7852828f7c..3ca59ae4cb 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1177,8 +1177,6 @@ pub const LibExeObjStep = struct { /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. glibc_multi_install_dir: ?[]const u8 = null, - dynamic_linker: ?[]const u8 = null, - /// Position Independent Code force_pic: ?bool = null, @@ -1978,6 +1976,11 @@ pub const LibExeObjStep = struct { } try zig_args.append(mcpu_buffer.toSliceConst()); } + + if (self.target.dynamic_linker.get()) |dynamic_linker| { + try zig_args.append("--dynamic-linker"); + try zig_args.append(dynamic_linker); + } } if (self.linker_script) |linker_script| { @@ -1985,11 +1988,6 @@ pub const LibExeObjStep = struct { zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable; } - if (self.dynamic_linker) |dynamic_linker| { - try zig_args.append("--dynamic-linker"); - try zig_args.append(dynamic_linker); - } - if (self.version_script) |version_script| { try zig_args.append("--version-script"); try zig_args.append(builder.pathFromRoot(version_script)); diff --git a/lib/std/target.zig b/lib/std/target.zig index 6ecb679f29..3054c60467 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -1099,16 +1099,52 @@ pub const Target = struct { } } + pub const DynamicLinker = struct { + /// Contains the memory used to store the dynamic linker path. This field should + /// not be used directly. See `get` and `set`. This field exists so that this API requires no allocator. + buffer: [255]u8 = undefined, + + /// Used to construct the dynamic linker path. This field should not be used + /// directly. See `get` and `set`. + max_byte: ?u8 = null, + + /// Asserts that the length is less than or equal to 255 bytes. + pub fn init(dl_or_null: ?[]const u8) DynamicLinker { + var result: DynamicLinker = undefined; + result.set(dl_or_null); + return result; + } + + /// The returned memory has the same lifetime as the `DynamicLinker`. + pub fn get(self: *const DynamicLinker) ?[]const u8 { + const m: usize = self.max_byte orelse return null; + return self.buffer[0 .. m + 1]; + } + + /// Asserts that the length is less than or equal to 255 bytes. + pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void { + if (dl_or_null) |dl| { + mem.copy(u8, &self.buffer, dl); + self.max_byte = @intCast(u8, dl.len - 1); + } else { + self.max_byte = null; + } + } + }; + /// The result will be a byte index *pointing at the final byte*. In other words, length minus one. /// A return value of `null` means the concept of a dynamic linker is not meaningful for that target. - pub fn standardDynamicLinkerPath(self: Target, buffer: *[255]u8) ?u8 { + pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { + var result: DynamicLinker = .{}; const S = struct { - fn print(b: *[255]u8, comptime fmt: []const u8, args: var) u8 { - return @intCast(u8, (std.fmt.bufPrint(b, fmt, args) catch unreachable).len - 1); + fn print(r: *DynamicLinker, comptime fmt: []const u8, args: var) DynamicLinker { + r.max_byte = @intCast(u8, (std.fmt.bufPrint(&r.buffer, fmt, args) catch unreachable).len - 1); + return r.*; } - fn copy(b: *[255]u8, s: []const u8) u8 { - mem.copy(u8, b, s); - return @intCast(u8, s.len - 1); + fn copy(r: *DynamicLinker, s: []const u8) DynamicLinker { + mem.copy(u8, &r.buffer, s); + r.max_byte = @intCast(u8, s.len - 1); + return r.*; } }; const print = S.print; @@ -1116,7 +1152,7 @@ pub const Target = struct { if (self.isAndroid()) { const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else ""; - return print(buffer, "/system/bin/linker{}", .{suffix}); + return print(&result, "/system/bin/linker{}", .{suffix}); } if (self.isMusl()) { @@ -1130,28 +1166,28 @@ pub const Target = struct { else => |arch| @tagName(arch), }; const arch_suffix = if (is_arm and self.getFloatAbi() == .hard) "hf" else ""; - return print(buffer, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); + return print(&result, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); } switch (self.os.tag) { - .freebsd => return copy(buffer, "/libexec/ld-elf.so.1"), - .netbsd => return copy(buffer, "/libexec/ld.elf_so"), - .dragonfly => return copy(buffer, "/libexec/ld-elf.so.2"), + .freebsd => return copy(&result, "/libexec/ld-elf.so.1"), + .netbsd => return copy(&result, "/libexec/ld.elf_so"), + .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"), .linux => switch (self.cpu.arch) { .i386, .sparc, .sparcel, - => return copy(buffer, "/lib/ld-linux.so.2"), + => return copy(&result, "/lib/ld-linux.so.2"), - .aarch64 => return copy(buffer, "/lib/ld-linux-aarch64.so.1"), - .aarch64_be => return copy(buffer, "/lib/ld-linux-aarch64_be.so.1"), - .aarch64_32 => return copy(buffer, "/lib/ld-linux-aarch64_32.so.1"), + .aarch64 => return copy(&result, "/lib/ld-linux-aarch64.so.1"), + .aarch64_be => return copy(&result, "/lib/ld-linux-aarch64_be.so.1"), + .aarch64_32 => return copy(&result, "/lib/ld-linux-aarch64_32.so.1"), .arm, .armeb, .thumb, .thumbeb, - => return copy(buffer, switch (self.getFloatAbi()) { + => return copy(&result, switch (self.getFloatAbi()) { .hard => "/lib/ld-linux-armhf.so.3", else => "/lib/ld-linux.so.3", }), @@ -1168,20 +1204,20 @@ pub const Target = struct { }; const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1"; - return print(buffer, "/lib{}/{}", .{ lib_suffix, loader }); + return print(&result, "/lib{}/{}", .{ lib_suffix, loader }); }, - .powerpc => return copy(buffer, "/lib/ld.so.1"), - .powerpc64, .powerpc64le => return copy(buffer, "/lib64/ld64.so.2"), - .s390x => return copy(buffer, "/lib64/ld64.so.1"), - .sparcv9 => return copy(buffer, "/lib64/ld-linux.so.2"), - .x86_64 => return copy(buffer, switch (self.abi) { + .powerpc => return copy(&result, "/lib/ld.so.1"), + .powerpc64, .powerpc64le => return copy(&result, "/lib64/ld64.so.2"), + .s390x => return copy(&result, "/lib64/ld64.so.1"), + .sparcv9 => return copy(&result, "/lib64/ld-linux.so.2"), + .x86_64 => return copy(&result, switch (self.abi) { .gnux32 => "/libx32/ld-linux-x32.so.2", else => "/lib64/ld-linux-x86-64.so.2", }), - .riscv32 => return copy(buffer, "/lib/ld-linux-riscv32-ilp32.so.1"), - .riscv64 => return copy(buffer, "/lib/ld-linux-riscv64-lp64.so.1"), + .riscv32 => return copy(&result, "/lib/ld-linux-riscv32-ilp32.so.1"), + .riscv64 => return copy(&result, "/lib/ld-linux-riscv64-lp64.so.1"), // Architectures in this list have been verified as not having a standard // dynamic linker path. @@ -1191,7 +1227,7 @@ pub const Target = struct { .bpfeb, .nvptx, .nvptx64, - => return null, + => return result, // TODO go over each item in this list and either move it to the above list, or // implement the standard dynamic linker path code for it. @@ -1217,7 +1253,7 @@ pub const Target = struct { .lanai, .renderscript32, .renderscript64, - => return null, + => return result, }, // Operating systems in this list have been verified as not having a standard @@ -1232,7 +1268,7 @@ pub const Target = struct { .emscripten, .wasi, .other, - => return null, + => return result, // TODO go over each item in this list and either move it to the above list, or // implement the standard dynamic linker path code for it. @@ -1259,7 +1295,7 @@ pub const Target = struct { .amdpal, .hermit, .hurd, - => return null, + => return result, } } }; diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index c7fd1f0464..212bc8eb9a 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -40,6 +40,10 @@ pub const CrossTarget = struct { /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. glibc_version: ?SemVer = null, + /// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path + /// based on the `os_tag`. + dynamic_linker: DynamicLinker = DynamicLinker{}, + pub const OsVersion = union(enum) { none: void, semver: SemVer, @@ -48,6 +52,8 @@ pub const CrossTarget = struct { pub const SemVer = std.builtin.Version; + pub const DynamicLinker = Target.DynamicLinker; + pub fn fromTarget(target: Target) CrossTarget { var result: CrossTarget = .{ .cpu_arch = target.cpu.arch, @@ -170,6 +176,10 @@ pub const CrossTarget = struct { /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline". cpu_features: ?[]const u8 = null, + /// Absolute path to dynamic linker, to override the default, which is either a natively + /// detected path, or a standard path. + dynamic_linker: ?[]const u8 = null, + /// If this is provided, the function will populate some information about parsing failures, /// so that user-friendly error messages can be delivered. diagnostics: ?*Diagnostics = null, @@ -199,8 +209,9 @@ pub const CrossTarget = struct { var dummy_diags: ParseOptions.Diagnostics = undefined; const diags = args.diagnostics orelse &dummy_diags; - // Start with everything initialized to default values. - var result: CrossTarget = .{}; + var result: CrossTarget = .{ + .dynamic_linker = DynamicLinker.init(args.dynamic_linker), + }; var it = mem.separate(args.arch_os_abi, "-"); const arch_name = it.next().?; @@ -446,7 +457,7 @@ pub const CrossTarget = struct { return self.cpu_arch == null and self.cpu_model == null and self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and self.os_tag == null and self.os_version_min == null and self.os_version_max == null and - self.abi == null; + self.abi == null and self.dynamic_linker.get() == null; } pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 { diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index ffae5c6015..44ff9af674 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -168,14 +168,9 @@ pub const NativePaths = struct { pub const NativeTargetInfo = struct { target: Target, - /// Contains the memory used to store the dynamic linker path. This field should - /// not be used directly. See `dynamicLinker` and `setDynamicLinker`. This field - /// exists so that this API requires no allocator. - dynamic_linker_buffer: [255]u8 = undefined, + dynamic_linker: DynamicLinker = DynamicLinker{}, - /// Used to construct the dynamic linker path. This field should not be used - /// directly. See `dynamicLinker` and `setDynamicLinker`. - dynamic_linker_max: ?u8 = null, + pub const DynamicLinker = Target.DynamicLinker; pub const DetectError = error{ OutOfMemory, @@ -220,21 +215,6 @@ pub const NativeTargetInfo = struct { return detectAbiAndDynamicLinker(allocator, cpu, os); } - /// The returned memory has the same lifetime as the `NativeTargetInfo`. - pub fn dynamicLinker(self: *const NativeTargetInfo) ?[]const u8 { - const m: usize = self.dynamic_linker_max orelse return null; - return self.dynamic_linker_buffer[0 .. m + 1]; - } - - pub fn setDynamicLinker(self: *NativeTargetInfo, dl_or_null: ?[]const u8) void { - if (dl_or_null) |dl| { - mem.copy(u8, &self.dynamic_linker_buffer, dl); - self.dynamic_linker_max = @intCast(u8, dl.len - 1); - } else { - self.dynamic_linker_max = null; - } - } - /// First we attempt to use the executable's own binary. If it is dynamically /// linked, then it should answer both the C ABI question and the dynamic linker question. /// If it is statically linked, then we try /usr/bin/env. If that does not provide the answer, then @@ -273,15 +253,14 @@ pub const NativeTargetInfo = struct { .os = os, .abi = abi, }; - const ld_info = &ld_info_list_buffer[ld_info_list_len]; - ld_info_list_len += 1; + const ld = target.standardDynamicLinkerPath(); + if (ld.get() == null) continue; - ld_info.* = .{ - .ld_path_buffer = undefined, - .ld_path_max = undefined, + ld_info_list_buffer[ld_info_list_len] = .{ + .ld = ld, .abi = abi, }; - ld_info.ld_path_max = target.standardDynamicLinkerPath(&ld_info.ld_path_buffer) orelse continue; + ld_info_list_len += 1; } const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; @@ -298,7 +277,7 @@ pub const NativeTargetInfo = struct { // This is O(N^M) but typical case here is N=2 and M=10. find_ld: for (lib_paths) |lib_path| { for (ld_info_list) |ld_info| { - const standard_ld_basename = fs.path.basename(ld_info.ldPath()); + const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) { found_ld_info = ld_info; found_ld_path = lib_path; @@ -329,8 +308,8 @@ pub const NativeTargetInfo = struct { .os = os_adjusted, .abi = found_ld_info.abi, }, + .dynamic_linker = DynamicLinker.init(found_ld_path), }; - result.setDynamicLinker(found_ld_path); return result; } @@ -472,18 +451,18 @@ pub const NativeTargetInfo = struct { elf.PT_INTERP => { const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); - if (p_filesz > result.dynamic_linker_buffer.len) return error.NameTooLong; - _ = try preadFull(env_file, result.dynamic_linker_buffer[0..p_filesz], p_offset, p_filesz); + if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; + _ = try preadFull(env_file, result.dynamic_linker.buffer[0..p_filesz], p_offset, p_filesz); // PT_INTERP includes a null byte in p_filesz. const len = p_filesz - 1; - // dynamic_linker_max is "max", not "len". - // We know it will fit in u8 because we check against dynamic_linker_buffer.len above. - result.dynamic_linker_max = @intCast(u8, len - 1); + // dynamic_linker.max_byte is "max", not "len". + // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. + result.dynamic_linker.max_byte = @intCast(u8, len - 1); // Use it to determine ABI. - const full_ld_path = result.dynamic_linker_buffer[0..len]; + const full_ld_path = result.dynamic_linker.buffer[0..len]; for (ld_info_list) |ld_info| { - const standard_ld_basename = fs.path.basename(ld_info.ldPath()); + const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) { result.target.abi = ld_info.abi; break; @@ -679,26 +658,20 @@ pub const NativeTargetInfo = struct { } fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo { - var result: NativeTargetInfo = .{ - .target = .{ - .cpu = cpu, - .os = os, - .abi = Target.Abi.default(cpu.arch, os), - }, + const target: Target = .{ + .cpu = cpu, + .os = os, + .abi = Target.Abi.default(cpu.arch, os), + }; + return NativeTargetInfo{ + .target = target, + .dynamic_linker = target.standardDynamicLinkerPath(), }; - result.dynamic_linker_max = result.target.standardDynamicLinkerPath(&result.dynamic_linker_buffer); - return result; } const LdInfo = struct { - ld_path_buffer: [255]u8, - ld_path_max: u8, + ld: DynamicLinker, abi: Target.Abi, - - pub fn ldPath(self: *const LdInfo) []const u8 { - const m: usize = self.ld_path_max; - return self.ld_path_buffer[0 .. m + 1]; - } }; fn elfInt(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_64) { diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index 3dae15056e..726c65937e 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -651,8 +651,9 @@ export fn stage2_target_parse( target: *Stage2Target, zig_triple: ?[*:0]const u8, mcpu: ?[*:0]const u8, + dynamic_linker: ?[*:0]const u8, ) Error { - stage2TargetParse(target, zig_triple, mcpu) catch |err| switch (err) { + stage2TargetParse(target, zig_triple, mcpu, dynamic_linker) catch |err| switch (err) { error.OutOfMemory => return .OutOfMemory, error.UnknownArchitecture => return .UnknownArchitecture, error.UnknownOperatingSystem => return .UnknownOperatingSystem, @@ -676,14 +677,17 @@ fn stage2TargetParse( stage1_target: *Stage2Target, zig_triple_oz: ?[*:0]const u8, mcpu_oz: ?[*:0]const u8, + dynamic_linker_oz: ?[*:0]const u8, ) !void { const target: CrossTarget = if (zig_triple_oz) |zig_triple_z| blk: { const zig_triple = mem.toSliceConst(u8, zig_triple_z); const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null; + const dynamic_linker = if (dynamic_linker_oz) |dl_z| mem.toSliceConst(u8, dl_z) else null; var diags: CrossTarget.ParseOptions.Diagnostics = .{}; break :blk CrossTarget.parse(.{ .arch_os_abi = zig_triple, .cpu_features = mcpu, + .dynamic_linker = dynamic_linker, .diagnostics = &diags, }) catch |err| switch (err) { error.UnknownCpuModel => { @@ -1170,7 +1174,7 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) if (cross_target.os_tag == null) { adjusted_target.os = detected_info.target.os; - if (detected_info.dynamicLinker()) |dl| { + if (detected_info.dynamic_linker.get()) |dl| { have_native_dl = true; dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); } @@ -1182,11 +1186,8 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) } } if (!have_native_dl) { - var buf: [255]u8 = undefined; - dynamic_linker_ptr.* = if (adjusted_target.standardDynamicLinkerPath(&buf)) |m| - try mem.dupeZ(std.heap.c_allocator, u8, buf[0 .. @as(usize, m) + 1]) - else - null; + const dl = adjusted_target.standardDynamicLinkerPath(); + dynamic_linker_ptr.* = if (dl.get()) |s| try mem.dupeZ(std.heap.c_allocator, u8, s) else null; } return adjusted_target; } diff --git a/src/all_types.hpp b/src/all_types.hpp index 838709b9c0..9f6bfd80a5 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2255,7 +2255,6 @@ struct CodeGen { Buf *test_name_prefix; Buf *zig_lib_dir; Buf *zig_std_dir; - Buf *dynamic_linker_path; Buf *version_script_path; const char **llvm_argv; diff --git a/src/codegen.cpp b/src/codegen.cpp index 8ae730616d..62f2c7a8ba 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8832,19 +8832,6 @@ static void init(CodeGen *g) { } } -static void detect_dynamic_linker(CodeGen *g) { - if (g->dynamic_linker_path != nullptr) - return; - if (!g->have_dynamic_link) - return; - if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic)) - return; - - if (g->zig_target->dynamic_linker != nullptr) { - g->dynamic_linker_path = buf_create_from_str(g->zig_target->dynamic_linker); - } -} - static void detect_libc(CodeGen *g) { Error err; @@ -10285,6 +10272,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_int(ch, g->zig_target->glibc_or_darwin_version->minor); cache_int(ch, g->zig_target->glibc_or_darwin_version->patch); } + if (g->zig_target->dynamic_linker != nullptr) { + cache_str(ch, g->zig_target->dynamic_linker); + } cache_int(ch, detect_subsystem(g)); cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); @@ -10325,7 +10315,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_str(ch, g->libc->msvc_lib_dir); cache_str(ch, g->libc->kernel32_lib_dir); } - cache_buf_opt(ch, g->dynamic_linker_path); cache_buf_opt(ch, g->version_script_path); // gen_c_objects appends objects to g->link_objects which we want to include in the hash @@ -10422,7 +10411,6 @@ void codegen_build_and_link(CodeGen *g) { g->have_err_ret_tracing = detect_err_ret_tracing(g); g->have_sanitize_c = detect_sanitize_c(g); detect_libc(g); - detect_dynamic_linker(g); Buf digest = BUF_INIT; if (g->enable_cache) { @@ -10619,7 +10607,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o child_gen->verbose_cc = parent_gen->verbose_cc; child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features; child_gen->llvm_argv = parent_gen->llvm_argv; - child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path; codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; diff --git a/src/link.cpp b/src/link.cpp index 588771d8bf..03534db3b2 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1751,9 +1751,9 @@ static void construct_linker_job_elf(LinkJob *lj) { } if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) { - assert(g->dynamic_linker_path != nullptr); + assert(g->zig_target->dynamic_linker != nullptr); lj->args.append("-dynamic-linker"); - lj->args.append(buf_ptr(g->dynamic_linker_path)); + lj->args.append(g->zig_target->dynamic_linker); } } diff --git a/src/main.cpp b/src/main.cpp index f471bda374..92d08bed4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -401,7 +401,7 @@ static int main0(int argc, char **argv) { bool link_eh_frame_hdr = false; ErrColor color = ErrColorAuto; CacheOpt enable_cache = CacheOptAuto; - Buf *dynamic_linker = nullptr; + const char *dynamic_linker = nullptr; const char *libc_txt = nullptr; ZigList clang_argv = {0}; ZigList lib_dirs = {0}; @@ -496,7 +496,7 @@ static int main0(int argc, char **argv) { os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); ZigTarget target; - if ((err = target_parse_triple(&target, "native", nullptr))) { + if ((err = target_parse_triple(&target, "native", nullptr, nullptr))) { fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); return EXIT_FAILURE; } @@ -766,7 +766,7 @@ static int main0(int argc, char **argv) { } else if (strcmp(arg, "--name") == 0) { out_name = argv[i]; } else if (strcmp(arg, "--dynamic-linker") == 0) { - dynamic_linker = buf_create_from_str(argv[i]); + dynamic_linker = argv[i]; } else if (strcmp(arg, "--libc") == 0) { libc_txt = argv[i]; } else if (strcmp(arg, "-D") == 0) { @@ -968,7 +968,7 @@ static int main0(int argc, char **argv) { init_all_targets(); ZigTarget target; - if ((err = target_parse_triple(&target, target_string, mcpu))) { + if ((err = target_parse_triple(&target, target_string, mcpu, dynamic_linker))) { fprintf(stderr, "invalid target: %s\n" "See `%s targets` to display valid targets.\n", err_str(err), arg0); return print_error_usage(arg0); @@ -1193,7 +1193,6 @@ static int main0(int argc, char **argv) { codegen_set_strip(g, strip); g->is_dynamic = is_dynamic; - g->dynamic_linker_path = dynamic_linker; g->verbose_tokenize = verbose_tokenize; g->verbose_ast = verbose_ast; g->verbose_link = verbose_link; @@ -1320,7 +1319,7 @@ static int main0(int argc, char **argv) { return main_exit(root_progress_node, EXIT_SUCCESS); } else if (cmd == CmdTest) { ZigTarget native; - if ((err = target_parse_triple(&native, "native", nullptr))) { + if ((err = target_parse_triple(&native, "native", nullptr, nullptr))) { fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); return EXIT_FAILURE; } diff --git a/src/stage2.cpp b/src/stage2.cpp index 67a518e1fa..1f6cb2d6aa 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -191,7 +191,9 @@ static void get_native_target(ZigTarget *target) { } } -Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu) { +Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, + const char *dynamic_linker) +{ Error err; if (zig_triple == nullptr) { @@ -249,6 +251,9 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons target->cache_hash = "\n\n"; } + if (dynamic_linker != nullptr) { + target->dynamic_linker = dynamic_linker; + } return ErrorNone; } diff --git a/src/stage2.h b/src/stage2.h index 20311788b2..b73269f4e8 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -298,7 +298,8 @@ struct ZigTarget { }; // ABI warning -ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu); +ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, + const char *dynamic_linker); // ABI warning diff --git a/src/target.cpp b/src/target.cpp index 96ac2e1666..f0030e05ac 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -410,8 +410,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si return ErrorUnknownABI; } -Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu) { - return stage2_target_parse(target, triple, mcpu); +Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker) { + return stage2_target_parse(target, triple, mcpu, dynamic_linker); } const char *target_arch_name(ZigLLVM_ArchType arch) { diff --git a/src/target.hpp b/src/target.hpp index 9c6e8ce46e..01f2c6b168 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -41,7 +41,7 @@ enum CIntType { CIntTypeCount, }; -Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu); +Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker); Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); -- cgit v1.2.3