mirror of
https://github.com/ziglang/zig.git
synced 2024-11-25 22:00:15 +00:00
Merge pull request #21617 from alexrp/target-dyld-stuff
Improve the `DynamicLinker` API and fix `detectAbiAndDynamicLinker()` for non-Linux/Hurd ELF hosts
This commit is contained in:
commit
e27b4647d8
@ -2059,30 +2059,6 @@ pub inline fn floatAbi(target: Target) FloatAbi {
|
||||
return target.abi.floatAbi();
|
||||
}
|
||||
|
||||
pub inline fn hasDynamicLinker(target: Target) bool {
|
||||
if (target.cpu.arch.isWasm()) {
|
||||
return false;
|
||||
}
|
||||
switch (target.os.tag) {
|
||||
.freestanding,
|
||||
.ios,
|
||||
.tvos,
|
||||
.watchos,
|
||||
.macos,
|
||||
.visionos,
|
||||
.uefi,
|
||||
.windows,
|
||||
.emscripten,
|
||||
.opencl,
|
||||
.opengl,
|
||||
.vulkan,
|
||||
.plan9,
|
||||
.other,
|
||||
=> return false,
|
||||
else => return true,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -2129,276 +2105,26 @@ pub const DynamicLinker = struct {
|
||||
return std.mem.eql(u8, lhs.buffer[0..lhs.len], rhs.buffer[0..rhs.len]);
|
||||
}
|
||||
|
||||
pub fn standard(cpu: Cpu, os: Os, abi: Abi) DynamicLinker {
|
||||
return switch (os.tag) {
|
||||
.fuchsia => init("ld.so.1"), // Fuchsia is unusual in that `DT_INTERP` is just a basename.
|
||||
pub const Kind = enum {
|
||||
/// No dynamic linker.
|
||||
none,
|
||||
/// Dynamic linker path is determined by the arch/OS components.
|
||||
arch_os,
|
||||
/// Dynamic linker path is determined by the arch/OS/ABI components.
|
||||
arch_os_abi,
|
||||
};
|
||||
|
||||
.haiku => init("/system/runtime_loader"),
|
||||
pub fn kind(os: Os.Tag) Kind {
|
||||
return switch (os) {
|
||||
.fuchsia,
|
||||
|
||||
.hurd => switch (cpu.arch) {
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
=> |arch| initFmt("/lib/ld-{s}{s}.so.1", .{
|
||||
@tagName(arch),
|
||||
if (abi == .gnuilp32) "_ilp32" else "",
|
||||
}),
|
||||
.haiku,
|
||||
.serenity,
|
||||
|
||||
.x86 => init("/lib/ld.so.1"),
|
||||
.x86_64 => initFmt("/lib/ld-{s}.so.1", .{if (abi == .gnux32) "x32" else "x86-64"}),
|
||||
|
||||
// These are unsupported by Hurd/glibc.
|
||||
.amdgcn,
|
||||
.arc,
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
.avr,
|
||||
.bpfel,
|
||||
.bpfeb,
|
||||
.csky,
|
||||
.hexagon,
|
||||
.kalimba,
|
||||
.lanai,
|
||||
.loongarch32,
|
||||
.loongarch64,
|
||||
.m68k,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.msp430,
|
||||
.nvptx,
|
||||
.nvptx64,
|
||||
.powerpc,
|
||||
.powerpcle,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
.propeller1,
|
||||
.propeller2,
|
||||
.riscv32,
|
||||
.riscv64,
|
||||
.s390x,
|
||||
.sparc,
|
||||
.sparc64,
|
||||
.spirv,
|
||||
.spirv32,
|
||||
.spirv64,
|
||||
.spu_2,
|
||||
.ve,
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
.xcore,
|
||||
.xtensa,
|
||||
=> none,
|
||||
},
|
||||
|
||||
.linux => if (abi.isAndroid())
|
||||
initFmt("/system/bin/linker{s}", .{if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else ""})
|
||||
else if (abi.isMusl())
|
||||
switch (cpu.arch) {
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.loongarch64,
|
||||
.m68k,
|
||||
.powerpc,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
.riscv32,
|
||||
.riscv64,
|
||||
.s390x,
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> |arch| initFmt("/lib/ld-musl-{s}{s}.so.1", .{
|
||||
switch (arch) {
|
||||
.thumb => "arm",
|
||||
.thumbeb => "armeb",
|
||||
.x86 => "i386",
|
||||
.x86_64 => if (abi == .muslx32) "x32" else "x86_64",
|
||||
else => @tagName(arch),
|
||||
},
|
||||
switch (arch) {
|
||||
.arm, .armeb, .thumb, .thumbeb => if (abi.floatAbi() == .hard) "hf" else "",
|
||||
.aarch64, .aarch64_be => if (abi == .gnuilp32) "_ilp32" else "",
|
||||
.riscv32, .riscv64 => if (std.Target.riscv.featureSetHas(cpu.features, .d))
|
||||
""
|
||||
else if (std.Target.riscv.featureSetHas(cpu.features, .f))
|
||||
"-sp"
|
||||
else
|
||||
"-sf",
|
||||
else => if (abi.floatAbi() == .soft) "-sf" else "",
|
||||
},
|
||||
}),
|
||||
|
||||
// The naming scheme for MIPS is a bit irregular.
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
=> |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}{s}.so.1", .{
|
||||
if (arch.isMIPS64()) "64" else "", // TODO: `n32` ABI support in LLVM 20.
|
||||
if (mips.featureSetHas(cpu.features, if (arch.isMIPS64()) .mips64r6 else .mips32r6)) "r6" else "",
|
||||
if (arch.endian() == .little) "el" else "",
|
||||
if (abi.floatAbi() == .soft) "-sf" else "",
|
||||
}),
|
||||
|
||||
// These are unsupported by musl.
|
||||
.amdgcn,
|
||||
.arc,
|
||||
.avr,
|
||||
.csky,
|
||||
.bpfel,
|
||||
.bpfeb,
|
||||
.hexagon,
|
||||
.kalimba,
|
||||
.lanai,
|
||||
.loongarch32,
|
||||
.msp430,
|
||||
.nvptx,
|
||||
.nvptx64,
|
||||
.powerpcle,
|
||||
.propeller1,
|
||||
.propeller2,
|
||||
.sparc,
|
||||
.sparc64,
|
||||
.spirv,
|
||||
.spirv32,
|
||||
.spirv64,
|
||||
.spu_2,
|
||||
.ve,
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
.xcore,
|
||||
.xtensa,
|
||||
=> none,
|
||||
}
|
||||
else if (abi.isGnu())
|
||||
switch (cpu.arch) {
|
||||
// TODO: `eb` architecture support.
|
||||
// TODO: `700` ABI support.
|
||||
.arc => init("/lib/ld-linux-arc.so.2"),
|
||||
|
||||
// TODO: OABI support (`/lib/ld-linux.so.2`).
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
=> initFmt("/lib/ld-linux{s}.so.3", .{if (abi.floatAbi() == .hard) "-armhf" else ""}),
|
||||
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
=> |arch| initFmt("/lib/ld-linux-{s}{s}.so.1", .{
|
||||
@tagName(arch),
|
||||
if (abi == .gnuilp32) "_ilp32" else "",
|
||||
}),
|
||||
|
||||
// TODO: `-be` architecture support.
|
||||
.csky => initFmt("/lib/ld-linux-cskyv2{s}.so.1", .{if (abi.floatAbi() == .hard) "-hf" else ""}),
|
||||
|
||||
.loongarch64 => initFmt("/lib64/ld-linux-loongarch-{s}.so.1", .{switch (abi) {
|
||||
.gnuf32 => "lp64f",
|
||||
.gnusf => "lp64s",
|
||||
else => "lp64d",
|
||||
}}),
|
||||
|
||||
.m68k => init("/lib/ld.so.1"),
|
||||
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
=> initFmt("/lib{s}/ld{s}.so.1", .{
|
||||
switch (abi) {
|
||||
.gnuabin32 => "32",
|
||||
.gnuabi64 => "64",
|
||||
else => "",
|
||||
},
|
||||
if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "",
|
||||
}),
|
||||
|
||||
.powerpc => init("/lib/ld.so.1"),
|
||||
// TODO: ELFv2 ABI opt-in support.
|
||||
.powerpc64 => init("/lib64/ld64.so.1"),
|
||||
.powerpc64le => init("/lib64/ld64.so.2"),
|
||||
|
||||
.riscv32,
|
||||
.riscv64,
|
||||
=> |arch| initFmt("/lib/ld-linux-{s}-{s}{s}.so.1", .{
|
||||
@tagName(arch),
|
||||
switch (arch) {
|
||||
.riscv32 => "ilp32",
|
||||
.riscv64 => "lp64",
|
||||
else => unreachable,
|
||||
},
|
||||
if (riscv.featureSetHas(cpu.features, .d))
|
||||
"d"
|
||||
else if (riscv.featureSetHas(cpu.features, .f))
|
||||
"f"
|
||||
else
|
||||
"",
|
||||
}),
|
||||
|
||||
.s390x => init("/lib/ld64.so.1"),
|
||||
|
||||
.sparc => init("/lib/ld-linux.so.2"),
|
||||
.sparc64 => init("/lib64/ld-linux.so.2"),
|
||||
|
||||
.x86 => init("/lib/ld-linux.so.2"),
|
||||
.x86_64 => init(if (abi == .gnux32) "/libx32/ld-linux-x32.so.2" else "/lib64/ld-linux-x86-64.so.2"),
|
||||
|
||||
.xtensa => init("/lib/ld.so.1"),
|
||||
|
||||
// These are unsupported by glibc.
|
||||
.amdgcn,
|
||||
.avr,
|
||||
.bpfeb,
|
||||
.bpfel,
|
||||
.hexagon,
|
||||
.kalimba,
|
||||
.lanai,
|
||||
.loongarch32,
|
||||
.msp430,
|
||||
.nvptx,
|
||||
.nvptx64,
|
||||
.powerpcle,
|
||||
.propeller1,
|
||||
.propeller2,
|
||||
.spirv,
|
||||
.spirv32,
|
||||
.spirv64,
|
||||
.spu_2,
|
||||
.ve,
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
.xcore,
|
||||
=> none,
|
||||
}
|
||||
else
|
||||
none, // Not a known Linux libc.
|
||||
|
||||
.serenity => init("/usr/lib/Loader.so"),
|
||||
|
||||
.dragonfly => initFmt("{s}/libexec/ld-elf.so.2", .{
|
||||
if (os.version_range.semver.isAtLeast(.{ .major = 3, .minor = 8, .patch = 0 }) orelse false)
|
||||
""
|
||||
else
|
||||
"/usr",
|
||||
}),
|
||||
|
||||
.freebsd => initFmt("{s}/libexec/ld-elf.so.1", .{
|
||||
if (os.version_range.semver.isAtLeast(.{ .major = 6, .minor = 0, .patch = 0 }) orelse false)
|
||||
""
|
||||
else
|
||||
"/usr",
|
||||
}),
|
||||
|
||||
.netbsd => init("/libexec/ld.elf_so"),
|
||||
|
||||
.openbsd => init("/usr/libexec/ld.so"),
|
||||
.dragonfly,
|
||||
.freebsd,
|
||||
.netbsd,
|
||||
.openbsd,
|
||||
|
||||
.bridgeos,
|
||||
.driverkit,
|
||||
@ -2407,11 +2133,410 @@ pub const DynamicLinker = struct {
|
||||
.tvos,
|
||||
.visionos,
|
||||
.watchos,
|
||||
=> init("/usr/lib/dyld"),
|
||||
|
||||
.illumos,
|
||||
.solaris,
|
||||
=> initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64/" else ""}),
|
||||
=> .arch_os,
|
||||
.hurd,
|
||||
.linux,
|
||||
=> .arch_os_abi,
|
||||
.freestanding,
|
||||
.other,
|
||||
|
||||
.contiki,
|
||||
.elfiamcu,
|
||||
.hermit,
|
||||
|
||||
.aix,
|
||||
.plan9,
|
||||
.rtems,
|
||||
.zos,
|
||||
|
||||
.uefi,
|
||||
.windows,
|
||||
|
||||
.emscripten,
|
||||
.wasi,
|
||||
|
||||
.amdhsa,
|
||||
.amdpal,
|
||||
.cuda,
|
||||
.mesa3d,
|
||||
.nvcl,
|
||||
.opencl,
|
||||
.opengl,
|
||||
.vulkan,
|
||||
|
||||
.ps3,
|
||||
.ps4,
|
||||
.ps5,
|
||||
=> .none,
|
||||
};
|
||||
}
|
||||
|
||||
/// The strictness of this function depends on the value of `kind(os.tag)`:
|
||||
///
|
||||
/// * `.none`: Ignores all arguments and just returns `none`.
|
||||
/// * `.arch_os`: Ignores `abi` and returns the dynamic linker matching `cpu` and `os`.
|
||||
/// * `.arch_os_abi`: Returns the dynamic linker matching `cpu`, `os`, and `abi`.
|
||||
///
|
||||
/// In the case of `.arch_os` in particular, callers should be aware that a valid dynamic linker
|
||||
/// being returned only means that the `cpu` + `os` combination represents a platform that
|
||||
/// actually exists and which has an established dynamic linker path that does not change with
|
||||
/// the ABI; it does not necessarily mean that `abi` makes any sense at all for that platform.
|
||||
/// The responsibility for determining whether `abi` is valid in this case rests with the
|
||||
/// caller. `Abi.default()` can be used to pick a best-effort default ABI for such platforms.
|
||||
pub fn standard(cpu: Cpu, os: Os, abi: Abi) DynamicLinker {
|
||||
return switch (os.tag) {
|
||||
.fuchsia => switch (cpu.arch) {
|
||||
.aarch64,
|
||||
.riscv64,
|
||||
.x86_64,
|
||||
=> init("ld.so.1"), // Fuchsia is unusual in that `DT_INTERP` is just a basename.
|
||||
else => none,
|
||||
},
|
||||
|
||||
.haiku => switch (cpu.arch) {
|
||||
.arm,
|
||||
.thumb,
|
||||
.aarch64,
|
||||
.m68k,
|
||||
.powerpc,
|
||||
.riscv64,
|
||||
.sparc64,
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> init("/system/runtime_loader"),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.hurd => switch (cpu.arch) {
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
=> |arch| initFmt("/lib/ld-{s}{s}.so.1", .{
|
||||
@tagName(arch),
|
||||
switch (abi) {
|
||||
.gnu => "",
|
||||
.gnuilp32 => "_ilp32",
|
||||
else => return none,
|
||||
},
|
||||
}),
|
||||
|
||||
.x86 => if (abi == .gnu) init("/lib/ld.so.1") else none,
|
||||
.x86_64 => initFmt("/lib/ld-{s}.so.1", .{switch (abi) {
|
||||
.gnu => "x86-64",
|
||||
.gnux32 => "x32",
|
||||
else => return none,
|
||||
}}),
|
||||
|
||||
else => none,
|
||||
},
|
||||
|
||||
.linux => if (abi.isAndroid())
|
||||
switch (cpu.arch) {
|
||||
.arm,
|
||||
.thumb,
|
||||
=> if (abi == .androideabi) init("/system/bin/linker") else none,
|
||||
|
||||
.aarch64,
|
||||
.riscv64,
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> if (abi == .android) initFmt("/system/bin/linker{s}", .{
|
||||
if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else "",
|
||||
}) else none,
|
||||
|
||||
else => none,
|
||||
}
|
||||
else if (abi.isMusl())
|
||||
switch (cpu.arch) {
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
=> |arch| initFmt("/lib/ld-musl-arm{s}{s}.so.1", .{
|
||||
if (arch == .armeb or arch == .thumbeb) "eb" else "",
|
||||
switch (abi) {
|
||||
.musleabi => "",
|
||||
.musleabihf => "hf",
|
||||
else => return none,
|
||||
},
|
||||
}),
|
||||
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.loongarch64, // TODO: `-sp` and `-sf` ABI support in LLVM 20.
|
||||
.m68k,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
.s390x,
|
||||
=> |arch| if (abi == .musl) initFmt("/lib/ld-musl-{s}.so.1", .{@tagName(arch)}) else none,
|
||||
|
||||
.mips,
|
||||
.mipsel,
|
||||
=> |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}.so.1", .{
|
||||
if (mips.featureSetHas(cpu.features, .mips32r6)) "r6" else "",
|
||||
if (arch == .mipsel) "el" else "",
|
||||
switch (abi) {
|
||||
.musleabi => "-sf",
|
||||
.musleabihf => "",
|
||||
else => return none,
|
||||
},
|
||||
}),
|
||||
|
||||
.mips64,
|
||||
.mips64el,
|
||||
=> |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}.so.1", .{
|
||||
// TODO: `n32` ABI support in LLVM 20.
|
||||
switch (abi) {
|
||||
.musl => "64",
|
||||
else => return none,
|
||||
},
|
||||
if (mips.featureSetHas(cpu.features, .mips64r6)) "r6" else "",
|
||||
if (arch == .mips64el) "el" else "",
|
||||
}),
|
||||
|
||||
.powerpc => initFmt("/lib/ld-musl-powerpc{s}.so.1", .{switch (abi) {
|
||||
.musleabi => "-sf",
|
||||
.musleabihf => "",
|
||||
else => return none,
|
||||
}}),
|
||||
|
||||
.riscv32,
|
||||
.riscv64,
|
||||
=> |arch| if (abi == .musl) initFmt("/lib/ld-musl-{s}{s}.so.1", .{
|
||||
@tagName(arch),
|
||||
if (riscv.featureSetHas(cpu.features, .d))
|
||||
""
|
||||
else if (riscv.featureSetHas(cpu.features, .f))
|
||||
"-sp"
|
||||
else
|
||||
"-sf",
|
||||
}) else none,
|
||||
|
||||
.x86 => if (abi == .musl) init("/lib/ld-musl-i386.so.1") else none,
|
||||
.x86_64 => initFmt("/lib/ld-musl-{s}.so.1", .{switch (abi) {
|
||||
.musl => "x86_64",
|
||||
.muslx32 => "x32",
|
||||
else => return none,
|
||||
}}),
|
||||
|
||||
else => none,
|
||||
}
|
||||
else if (abi.isGnu())
|
||||
switch (cpu.arch) {
|
||||
// TODO: `eb` architecture support.
|
||||
// TODO: `700` ABI support.
|
||||
.arc => if (abi == .gnu) init("/lib/ld-linux-arc.so.2") else none,
|
||||
|
||||
// TODO: OABI support (`/lib/ld-linux.so.2`).
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
=> initFmt("/lib/ld-linux{s}.so.3", .{switch (abi) {
|
||||
.gnueabi => "",
|
||||
.gnueabihf => "-armhf",
|
||||
else => return none,
|
||||
}}),
|
||||
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
=> |arch| initFmt("/lib/ld-linux-{s}{s}.so.1", .{
|
||||
@tagName(arch),
|
||||
switch (abi) {
|
||||
.gnu => "",
|
||||
.gnuilp32 => "_ilp32",
|
||||
else => return none,
|
||||
},
|
||||
}),
|
||||
|
||||
// TODO: `-be` architecture support.
|
||||
.csky => initFmt("/lib/ld-linux-cskyv2{s}.so.1", .{switch (abi) {
|
||||
.gnueabi => "",
|
||||
.gnueabihf => "-hf",
|
||||
else => return none,
|
||||
}}),
|
||||
|
||||
.loongarch64 => initFmt("/lib64/ld-linux-loongarch-{s}.so.1", .{switch (abi) {
|
||||
.gnu => "lp64d",
|
||||
.gnuf32 => "lp64f",
|
||||
.gnusf => "lp64s",
|
||||
else => return none,
|
||||
}}),
|
||||
|
||||
.m68k => if (abi == .gnu) init("/lib/ld.so.1") else none,
|
||||
|
||||
.mips,
|
||||
.mipsel,
|
||||
=> switch (abi) {
|
||||
.gnueabi,
|
||||
.gnueabihf,
|
||||
=> initFmt("/lib/ld{s}.so.1", .{
|
||||
if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "",
|
||||
}),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.mips64,
|
||||
.mips64el,
|
||||
=> initFmt("/lib{s}/ld{s}.so.1", .{
|
||||
switch (abi) {
|
||||
.gnuabi64 => "64",
|
||||
.gnuabin32 => "32",
|
||||
else => return none,
|
||||
},
|
||||
if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "",
|
||||
}),
|
||||
|
||||
.powerpc => switch (abi) {
|
||||
.gnueabi,
|
||||
.gnueabihf,
|
||||
=> init("/lib/ld.so.1"),
|
||||
else => none,
|
||||
},
|
||||
// TODO: ELFv2 ABI (`/lib64/ld64.so.2`) opt-in support.
|
||||
.powerpc64 => if (abi == .gnu) init("/lib64/ld64.so.1") else none,
|
||||
.powerpc64le => if (abi == .gnu) init("/lib64/ld64.so.2") else none,
|
||||
|
||||
.riscv32,
|
||||
.riscv64,
|
||||
=> |arch| if (abi == .gnu) initFmt("/lib/ld-linux-{s}{s}.so.1", .{
|
||||
switch (arch) {
|
||||
.riscv32 => "riscv32-ilp32",
|
||||
.riscv64 => "riscv64-lp64",
|
||||
else => unreachable,
|
||||
},
|
||||
if (riscv.featureSetHas(cpu.features, .d))
|
||||
"d"
|
||||
else if (riscv.featureSetHas(cpu.features, .f))
|
||||
"f"
|
||||
else
|
||||
"",
|
||||
}) else none,
|
||||
|
||||
.s390x => if (abi == .gnu) init("/lib/ld64.so.1") else none,
|
||||
|
||||
.sparc => if (abi == .gnu) init("/lib/ld-linux.so.2") else none,
|
||||
.sparc64 => if (abi == .gnu) init("/lib64/ld-linux.so.2") else none,
|
||||
|
||||
.x86 => if (abi == .gnu) init("/lib/ld-linux.so.2") else none,
|
||||
.x86_64 => switch (abi) {
|
||||
.gnu => init("/lib64/ld-linux-x86-64.so.2"),
|
||||
.gnux32 => init("/libx32/ld-linux-x32.so.2"),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.xtensa => if (abi == .gnu) init("/lib/ld.so.1") else none,
|
||||
|
||||
else => none,
|
||||
}
|
||||
else
|
||||
none, // Not a known Linux libc.
|
||||
|
||||
.serenity => switch (cpu.arch) {
|
||||
.aarch64,
|
||||
.riscv64,
|
||||
.x86_64,
|
||||
=> init("/usr/lib/Loader.so"),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.dragonfly => if (cpu.arch == .x86_64) initFmt("{s}/libexec/ld-elf.so.2", .{
|
||||
if (os.version_range.semver.isAtLeast(.{ .major = 3, .minor = 8, .patch = 0 }) orelse false)
|
||||
""
|
||||
else
|
||||
"/usr",
|
||||
}) else none,
|
||||
|
||||
.freebsd => switch (cpu.arch) {
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
.aarch64,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.powerpc,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
.riscv64,
|
||||
.sparc64,
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> initFmt("{s}/libexec/ld-elf.so.1", .{
|
||||
if (os.version_range.semver.isAtLeast(.{ .major = 6, .minor = 0, .patch = 0 }) orelse false)
|
||||
""
|
||||
else
|
||||
"/usr",
|
||||
}),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.netbsd => switch (cpu.arch) {
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.m68k,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.powerpc,
|
||||
.riscv64,
|
||||
.sparc,
|
||||
.sparc64,
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> init("/libexec/ld.elf_so"),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.openbsd => switch (cpu.arch) {
|
||||
.arm,
|
||||
.thumb,
|
||||
.aarch64,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.powerpc,
|
||||
.powerpc64,
|
||||
.riscv64,
|
||||
.sparc64,
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> init("/usr/libexec/ld.so"),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.bridgeos => if (cpu.arch == .aarch64) init("/usr/lib/dyld") else none,
|
||||
.driverkit,
|
||||
.ios,
|
||||
.macos,
|
||||
.tvos,
|
||||
.visionos,
|
||||
.watchos,
|
||||
=> switch (cpu.arch) {
|
||||
.aarch64,
|
||||
.x86_64,
|
||||
=> init("/usr/lib/dyld"),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.illumos,
|
||||
.solaris,
|
||||
=> switch (cpu.arch) {
|
||||
.sparc,
|
||||
.sparc64,
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, .none) == 64) "64/" else ""}),
|
||||
else => none,
|
||||
},
|
||||
|
||||
// Operating systems in this list have been verified as not having a standard
|
||||
// dynamic linker path.
|
||||
|
@ -967,14 +967,15 @@ fn detectAbiAndDynamicLinker(
|
||||
os: Target.Os,
|
||||
query: Target.Query,
|
||||
) DetectError!Target {
|
||||
const native_target_has_ld = comptime builtin.target.hasDynamicLinker();
|
||||
const native_target_has_ld = comptime Target.DynamicLinker.kind(builtin.os.tag) != .none;
|
||||
const is_linux = builtin.target.os.tag == .linux;
|
||||
const is_solarish = builtin.target.os.tag.isSolarish();
|
||||
const is_darwin = builtin.target.os.tag.isDarwin();
|
||||
const have_all_info = query.dynamic_linker.get() != null and
|
||||
query.abi != null and (!is_linux or query.abi.?.isGnu());
|
||||
const os_is_non_native = query.os_tag != null;
|
||||
// The Solaris/illumos environment is always the same.
|
||||
if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) {
|
||||
if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish or is_darwin) {
|
||||
return defaultAbiAndDynamicLinker(cpu, os, query);
|
||||
}
|
||||
if (query.abi) |abi| {
|
||||
@ -999,26 +1000,33 @@ fn detectAbiAndDynamicLinker(
|
||||
};
|
||||
var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
|
||||
var ld_info_list_len: usize = 0;
|
||||
const ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
|
||||
|
||||
for (all_abis) |abi| {
|
||||
// This may be a nonsensical parameter. We detect this with
|
||||
// error.UnknownDynamicLinkerPath and skip adding it to `ld_info_list`.
|
||||
const target: Target = .{
|
||||
.cpu = cpu,
|
||||
.os = os,
|
||||
.abi = abi,
|
||||
.ofmt = ofmt,
|
||||
};
|
||||
const ld = target.standardDynamicLinkerPath();
|
||||
if (ld.get() == null) continue;
|
||||
switch (Target.DynamicLinker.kind(os.tag)) {
|
||||
// The OS has no dynamic linker. Leave the list empty and rely on `Abi.default()` to pick
|
||||
// something sensible in `abiAndDynamicLinkerFromFile()`.
|
||||
.none => {},
|
||||
// The OS has a system-wide dynamic linker. Unfortunately, this implies that there's no
|
||||
// useful ABI information that we can glean from it merely being present. That means the
|
||||
// best we can do for this case (for now) is also `Abi.default()`.
|
||||
.arch_os => {},
|
||||
// The OS can have different dynamic linker paths depending on libc/ABI. In this case, we
|
||||
// need to gather all the valid arch/OS/ABI combinations. `abiAndDynamicLinkerFromFile()`
|
||||
// will then look for a dynamic linker with a matching path on the system and pick the ABI
|
||||
// we associated it with here.
|
||||
.arch_os_abi => for (all_abis) |abi| {
|
||||
const ld = Target.DynamicLinker.standard(cpu, os, abi);
|
||||
|
||||
ld_info_list_buffer[ld_info_list_len] = .{
|
||||
.ld = ld,
|
||||
.abi = abi,
|
||||
};
|
||||
ld_info_list_len += 1;
|
||||
// Does the generated target triple actually have a standard dynamic linker path?
|
||||
if (ld.get() == null) continue;
|
||||
|
||||
ld_info_list_buffer[ld_info_list_len] = .{
|
||||
.ld = ld,
|
||||
.abi = abi,
|
||||
};
|
||||
ld_info_list_len += 1;
|
||||
},
|
||||
}
|
||||
|
||||
const ld_info_list = ld_info_list_buffer[0..ld_info_list_len];
|
||||
|
||||
// Best case scenario: the executable is dynamically linked, and we can iterate
|
||||
|
@ -249,10 +249,12 @@ const targets = [_]std.Target.Query{
|
||||
.{ .cpu_arch = .s390x, .os_tag = .zos, .abi = .none },
|
||||
|
||||
.{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },
|
||||
.{ .cpu_arch = .sparc, .os_tag = .illumos, .abi = .none },
|
||||
.{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },
|
||||
.{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .none },
|
||||
.{ .cpu_arch = .sparc, .os_tag = .netbsd, .abi = .none },
|
||||
.{ .cpu_arch = .sparc, .os_tag = .rtems, .abi = .none },
|
||||
.{ .cpu_arch = .sparc, .os_tag = .solaris, .abi = .none },
|
||||
|
||||
.{ .cpu_arch = .sparc64, .os_tag = .freebsd, .abi = .none },
|
||||
.{ .cpu_arch = .sparc64, .os_tag = .freestanding, .abi = .none },
|
||||
@ -269,6 +271,9 @@ const targets = [_]std.Target.Query{
|
||||
.{ .cpu_arch = .thumb, .os_tag = .freebsd, .abi = .eabihf },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .freestanding, .abi = .eabi },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .freestanding, .abi = .eabihf },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .haiku, .abi = .eabi },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .haiku, .abi = .eabihf },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .androideabi },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .eabi },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .eabihf },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .musleabi },
|
||||
@ -314,6 +319,7 @@ const targets = [_]std.Target.Query{
|
||||
.{ .cpu_arch = .x86, .os_tag = .freestanding, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .haiku, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .hurd, .abi = .gnu },
|
||||
.{ .cpu_arch = .x86, .os_tag = .illumos, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .linux, .abi = .android },
|
||||
.{ .cpu_arch = .x86, .os_tag = .linux, .abi = .gnu },
|
||||
.{ .cpu_arch = .x86, .os_tag = .linux, .abi = .musl },
|
||||
@ -322,6 +328,7 @@ const targets = [_]std.Target.Query{
|
||||
.{ .cpu_arch = .x86, .os_tag = .netbsd, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .openbsd, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .rtems, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .solaris, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .uefi, .abi = .none },
|
||||
.{ .cpu_arch = .x86, .os_tag = .windows, .abi = .gnu },
|
||||
.{ .cpu_arch = .x86, .os_tag = .windows, .abi = .itanium },
|
||||
|
Loading…
Reference in New Issue
Block a user