authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-02 10:29:41+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-11-02 10:29:41+01:00
loge27b4647d86e3bdaf2c4fd95db2e7d359afd7fc4
treea979dd3e143102fea636ae9c5dc7fc61a81aa8b5
parent8abbdb56a4fce176cb8ec24e5d4724ac16196a0b
parent059f18855f18f9dd76f74031381e04dd131da528
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21617 from alexrp/target-dyld-stuff

Improve the `DynamicLinker` API and fix `detectAbiAndDynamicLinker()` for non-Linux/Hurd ELF hosts

3 files changed, 357 insertions(+), 217 deletions(-)

lib/std/Target.zig+322-197
......@@ -2059,30 +2059,6 @@ pub inline fn floatAbi(target: Target) FloatAbi {
20592059 return target.abi.floatAbi();
20602060}
20612061
2062pub inline fn hasDynamicLinker(target: Target) bool {
2063 if (target.cpu.arch.isWasm()) {
2064 return false;
2065 }
2066 switch (target.os.tag) {
2067 .freestanding,
2068 .ios,
2069 .tvos,
2070 .watchos,
2071 .macos,
2072 .visionos,
2073 .uefi,
2074 .windows,
2075 .emscripten,
2076 .opencl,
2077 .opengl,
2078 .vulkan,
2079 .plan9,
2080 .other,
2081 => return false,
2082 else => return true,
2083 }
2084}
2085
20862062pub const DynamicLinker = struct {
20872063 /// Contains the memory used to store the dynamic linker path. This field
20882064 /// should not be used directly. See `get` and `set`. This field exists so
......@@ -2129,209 +2105,306 @@ pub const DynamicLinker = struct {
21292105 return std.mem.eql(u8, lhs.buffer[0..lhs.len], rhs.buffer[0..rhs.len]);
21302106 }
21312107
2108 pub const Kind = enum {
2109 /// No dynamic linker.
2110 none,
2111 /// Dynamic linker path is determined by the arch/OS components.
2112 arch_os,
2113 /// Dynamic linker path is determined by the arch/OS/ABI components.
2114 arch_os_abi,
2115 };
2116
2117 pub fn kind(os: Os.Tag) Kind {
2118 return switch (os) {
2119 .fuchsia,
2120
2121 .haiku,
2122 .serenity,
2123
2124 .dragonfly,
2125 .freebsd,
2126 .netbsd,
2127 .openbsd,
2128
2129 .bridgeos,
2130 .driverkit,
2131 .ios,
2132 .macos,
2133 .tvos,
2134 .visionos,
2135 .watchos,
2136
2137 .illumos,
2138 .solaris,
2139 => .arch_os,
2140 .hurd,
2141 .linux,
2142 => .arch_os_abi,
2143 .freestanding,
2144 .other,
2145
2146 .contiki,
2147 .elfiamcu,
2148 .hermit,
2149
2150 .aix,
2151 .plan9,
2152 .rtems,
2153 .zos,
2154
2155 .uefi,
2156 .windows,
2157
2158 .emscripten,
2159 .wasi,
2160
2161 .amdhsa,
2162 .amdpal,
2163 .cuda,
2164 .mesa3d,
2165 .nvcl,
2166 .opencl,
2167 .opengl,
2168 .vulkan,
2169
2170 .ps3,
2171 .ps4,
2172 .ps5,
2173 => .none,
2174 };
2175 }
2176
2177 /// The strictness of this function depends on the value of `kind(os.tag)`:
2178 ///
2179 /// * `.none`: Ignores all arguments and just returns `none`.
2180 /// * `.arch_os`: Ignores `abi` and returns the dynamic linker matching `cpu` and `os`.
2181 /// * `.arch_os_abi`: Returns the dynamic linker matching `cpu`, `os`, and `abi`.
2182 ///
2183 /// In the case of `.arch_os` in particular, callers should be aware that a valid dynamic linker
2184 /// being returned only means that the `cpu` + `os` combination represents a platform that
2185 /// actually exists and which has an established dynamic linker path that does not change with
2186 /// the ABI; it does not necessarily mean that `abi` makes any sense at all for that platform.
2187 /// The responsibility for determining whether `abi` is valid in this case rests with the
2188 /// caller. `Abi.default()` can be used to pick a best-effort default ABI for such platforms.
21322189 pub fn standard(cpu: Cpu, os: Os, abi: Abi) DynamicLinker {
21332190 return switch (os.tag) {
2134 .fuchsia => init("ld.so.1"), // Fuchsia is unusual in that `DT_INTERP` is just a basename.
2191 .fuchsia => switch (cpu.arch) {
2192 .aarch64,
2193 .riscv64,
2194 .x86_64,
2195 => init("ld.so.1"), // Fuchsia is unusual in that `DT_INTERP` is just a basename.
2196 else => none,
2197 },
21352198
2136 .haiku => init("/system/runtime_loader"),
2199 .haiku => switch (cpu.arch) {
2200 .arm,
2201 .thumb,
2202 .aarch64,
2203 .m68k,
2204 .powerpc,
2205 .riscv64,
2206 .sparc64,
2207 .x86,
2208 .x86_64,
2209 => init("/system/runtime_loader"),
2210 else => none,
2211 },
21372212
21382213 .hurd => switch (cpu.arch) {
21392214 .aarch64,
21402215 .aarch64_be,
21412216 => |arch| initFmt("/lib/ld-{s}{s}.so.1", .{
21422217 @tagName(arch),
2143 if (abi == .gnuilp32) "_ilp32" else "",
2218 switch (abi) {
2219 .gnu => "",
2220 .gnuilp32 => "_ilp32",
2221 else => return none,
2222 },
21442223 }),
21452224
2146 .x86 => init("/lib/ld.so.1"),
2147 .x86_64 => initFmt("/lib/ld-{s}.so.1", .{if (abi == .gnux32) "x32" else "x86-64"}),
2225 .x86 => if (abi == .gnu) init("/lib/ld.so.1") else none,
2226 .x86_64 => initFmt("/lib/ld-{s}.so.1", .{switch (abi) {
2227 .gnu => "x86-64",
2228 .gnux32 => "x32",
2229 else => return none,
2230 }}),
21482231
2149 // These are unsupported by Hurd/glibc.
2150 .amdgcn,
2151 .arc,
2152 .arm,
2153 .armeb,
2154 .thumb,
2155 .thumbeb,
2156 .avr,
2157 .bpfel,
2158 .bpfeb,
2159 .csky,
2160 .hexagon,
2161 .kalimba,
2162 .lanai,
2163 .loongarch32,
2164 .loongarch64,
2165 .m68k,
2166 .mips,
2167 .mipsel,
2168 .mips64,
2169 .mips64el,
2170 .msp430,
2171 .nvptx,
2172 .nvptx64,
2173 .powerpc,
2174 .powerpcle,
2175 .powerpc64,
2176 .powerpc64le,
2177 .propeller1,
2178 .propeller2,
2179 .riscv32,
2180 .riscv64,
2181 .s390x,
2182 .sparc,
2183 .sparc64,
2184 .spirv,
2185 .spirv32,
2186 .spirv64,
2187 .spu_2,
2188 .ve,
2189 .wasm32,
2190 .wasm64,
2191 .xcore,
2192 .xtensa,
2193 => none,
2232 else => none,
21942233 },
21952234
21962235 .linux => if (abi.isAndroid())
2197 initFmt("/system/bin/linker{s}", .{if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else ""})
2236 switch (cpu.arch) {
2237 .arm,
2238 .thumb,
2239 => if (abi == .androideabi) init("/system/bin/linker") else none,
2240
2241 .aarch64,
2242 .riscv64,
2243 .x86,
2244 .x86_64,
2245 => if (abi == .android) initFmt("/system/bin/linker{s}", .{
2246 if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else "",
2247 }) else none,
2248
2249 else => none,
2250 }
21982251 else if (abi.isMusl())
21992252 switch (cpu.arch) {
22002253 .arm,
22012254 .armeb,
22022255 .thumb,
22032256 .thumbeb,
2257 => |arch| initFmt("/lib/ld-musl-arm{s}{s}.so.1", .{
2258 if (arch == .armeb or arch == .thumbeb) "eb" else "",
2259 switch (abi) {
2260 .musleabi => "",
2261 .musleabihf => "hf",
2262 else => return none,
2263 },
2264 }),
2265
22042266 .aarch64,
22052267 .aarch64_be,
2206 .loongarch64,
2268 .loongarch64, // TODO: `-sp` and `-sf` ABI support in LLVM 20.
22072269 .m68k,
2208 .powerpc,
22092270 .powerpc64,
22102271 .powerpc64le,
2211 .riscv32,
2212 .riscv64,
22132272 .s390x,
2214 .x86,
2215 .x86_64,
2216 => |arch| initFmt("/lib/ld-musl-{s}{s}.so.1", .{
2217 switch (arch) {
2218 .thumb => "arm",
2219 .thumbeb => "armeb",
2220 .x86 => "i386",
2221 .x86_64 => if (abi == .muslx32) "x32" else "x86_64",
2222 else => @tagName(arch),
2223 },
2224 switch (arch) {
2225 .arm, .armeb, .thumb, .thumbeb => if (abi.floatAbi() == .hard) "hf" else "",
2226 .aarch64, .aarch64_be => if (abi == .gnuilp32) "_ilp32" else "",
2227 .riscv32, .riscv64 => if (std.Target.riscv.featureSetHas(cpu.features, .d))
2228 ""
2229 else if (std.Target.riscv.featureSetHas(cpu.features, .f))
2230 "-sp"
2231 else
2232 "-sf",
2233 else => if (abi.floatAbi() == .soft) "-sf" else "",
2234 },
2235 }),
2273 => |arch| if (abi == .musl) initFmt("/lib/ld-musl-{s}.so.1", .{@tagName(arch)}) else none,
22362274
2237 // The naming scheme for MIPS is a bit irregular.
22382275 .mips,
22392276 .mipsel,
2277 => |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}.so.1", .{
2278 if (mips.featureSetHas(cpu.features, .mips32r6)) "r6" else "",
2279 if (arch == .mipsel) "el" else "",
2280 switch (abi) {
2281 .musleabi => "-sf",
2282 .musleabihf => "",
2283 else => return none,
2284 },
2285 }),
2286
22402287 .mips64,
22412288 .mips64el,
2242 => |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}{s}.so.1", .{
2243 if (arch.isMIPS64()) "64" else "", // TODO: `n32` ABI support in LLVM 20.
2244 if (mips.featureSetHas(cpu.features, if (arch.isMIPS64()) .mips64r6 else .mips32r6)) "r6" else "",
2245 if (arch.endian() == .little) "el" else "",
2246 if (abi.floatAbi() == .soft) "-sf" else "",
2289 => |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}.so.1", .{
2290 // TODO: `n32` ABI support in LLVM 20.
2291 switch (abi) {
2292 .musl => "64",
2293 else => return none,
2294 },
2295 if (mips.featureSetHas(cpu.features, .mips64r6)) "r6" else "",
2296 if (arch == .mips64el) "el" else "",
22472297 }),
22482298
2249 // These are unsupported by musl.
2250 .amdgcn,
2251 .arc,
2252 .avr,
2253 .csky,
2254 .bpfel,
2255 .bpfeb,
2256 .hexagon,
2257 .kalimba,
2258 .lanai,
2259 .loongarch32,
2260 .msp430,
2261 .nvptx,
2262 .nvptx64,
2263 .powerpcle,
2264 .propeller1,
2265 .propeller2,
2266 .sparc,
2267 .sparc64,
2268 .spirv,
2269 .spirv32,
2270 .spirv64,
2271 .spu_2,
2272 .ve,
2273 .wasm32,
2274 .wasm64,
2275 .xcore,
2276 .xtensa,
2277 => none,
2299 .powerpc => initFmt("/lib/ld-musl-powerpc{s}.so.1", .{switch (abi) {
2300 .musleabi => "-sf",
2301 .musleabihf => "",
2302 else => return none,
2303 }}),
2304
2305 .riscv32,
2306 .riscv64,
2307 => |arch| if (abi == .musl) initFmt("/lib/ld-musl-{s}{s}.so.1", .{
2308 @tagName(arch),
2309 if (riscv.featureSetHas(cpu.features, .d))
2310 ""
2311 else if (riscv.featureSetHas(cpu.features, .f))
2312 "-sp"
2313 else
2314 "-sf",
2315 }) else none,
2316
2317 .x86 => if (abi == .musl) init("/lib/ld-musl-i386.so.1") else none,
2318 .x86_64 => initFmt("/lib/ld-musl-{s}.so.1", .{switch (abi) {
2319 .musl => "x86_64",
2320 .muslx32 => "x32",
2321 else => return none,
2322 }}),
2323
2324 else => none,
22782325 }
22792326 else if (abi.isGnu())
22802327 switch (cpu.arch) {
22812328 // TODO: `eb` architecture support.
22822329 // TODO: `700` ABI support.
2283 .arc => init("/lib/ld-linux-arc.so.2"),
2330 .arc => if (abi == .gnu) init("/lib/ld-linux-arc.so.2") else none,
22842331
22852332 // TODO: OABI support (`/lib/ld-linux.so.2`).
22862333 .arm,
22872334 .armeb,
22882335 .thumb,
22892336 .thumbeb,
2290 => initFmt("/lib/ld-linux{s}.so.3", .{if (abi.floatAbi() == .hard) "-armhf" else ""}),
2337 => initFmt("/lib/ld-linux{s}.so.3", .{switch (abi) {
2338 .gnueabi => "",
2339 .gnueabihf => "-armhf",
2340 else => return none,
2341 }}),
22912342
22922343 .aarch64,
22932344 .aarch64_be,
22942345 => |arch| initFmt("/lib/ld-linux-{s}{s}.so.1", .{
22952346 @tagName(arch),
2296 if (abi == .gnuilp32) "_ilp32" else "",
2347 switch (abi) {
2348 .gnu => "",
2349 .gnuilp32 => "_ilp32",
2350 else => return none,
2351 },
22972352 }),
22982353
22992354 // TODO: `-be` architecture support.
2300 .csky => initFmt("/lib/ld-linux-cskyv2{s}.so.1", .{if (abi.floatAbi() == .hard) "-hf" else ""}),
2355 .csky => initFmt("/lib/ld-linux-cskyv2{s}.so.1", .{switch (abi) {
2356 .gnueabi => "",
2357 .gnueabihf => "-hf",
2358 else => return none,
2359 }}),
23012360
23022361 .loongarch64 => initFmt("/lib64/ld-linux-loongarch-{s}.so.1", .{switch (abi) {
2362 .gnu => "lp64d",
23032363 .gnuf32 => "lp64f",
23042364 .gnusf => "lp64s",
2305 else => "lp64d",
2365 else => return none,
23062366 }}),
23072367
2308 .m68k => init("/lib/ld.so.1"),
2368 .m68k => if (abi == .gnu) init("/lib/ld.so.1") else none,
23092369
23102370 .mips,
23112371 .mipsel,
2372 => switch (abi) {
2373 .gnueabi,
2374 .gnueabihf,
2375 => initFmt("/lib/ld{s}.so.1", .{
2376 if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "",
2377 }),
2378 else => none,
2379 },
2380
23122381 .mips64,
23132382 .mips64el,
23142383 => initFmt("/lib{s}/ld{s}.so.1", .{
23152384 switch (abi) {
2316 .gnuabin32 => "32",
23172385 .gnuabi64 => "64",
2318 else => "",
2386 .gnuabin32 => "32",
2387 else => return none,
23192388 },
23202389 if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "",
23212390 }),
23222391
2323 .powerpc => init("/lib/ld.so.1"),
2324 // TODO: ELFv2 ABI opt-in support.
2325 .powerpc64 => init("/lib64/ld64.so.1"),
2326 .powerpc64le => init("/lib64/ld64.so.2"),
2392 .powerpc => switch (abi) {
2393 .gnueabi,
2394 .gnueabihf,
2395 => init("/lib/ld.so.1"),
2396 else => none,
2397 },
2398 // TODO: ELFv2 ABI (`/lib64/ld64.so.2`) opt-in support.
2399 .powerpc64 => if (abi == .gnu) init("/lib64/ld64.so.1") else none,
2400 .powerpc64le => if (abi == .gnu) init("/lib64/ld64.so.2") else none,
23272401
23282402 .riscv32,
23292403 .riscv64,
2330 => |arch| initFmt("/lib/ld-linux-{s}-{s}{s}.so.1", .{
2331 @tagName(arch),
2404 => |arch| if (abi == .gnu) initFmt("/lib/ld-linux-{s}{s}.so.1", .{
23322405 switch (arch) {
2333 .riscv32 => "ilp32",
2334 .riscv64 => "lp64",
2406 .riscv32 => "riscv32-ilp32",
2407 .riscv64 => "riscv64-lp64",
23352408 else => unreachable,
23362409 },
23372410 if (riscv.featureSetHas(cpu.features, .d))
......@@ -2340,78 +2413,130 @@ pub const DynamicLinker = struct {
23402413 "f"
23412414 else
23422415 "",
2343 }),
2416 }) else none,
23442417
2345 .s390x => init("/lib/ld64.so.1"),
2418 .s390x => if (abi == .gnu) init("/lib/ld64.so.1") else none,
23462419
2347 .sparc => init("/lib/ld-linux.so.2"),
2348 .sparc64 => init("/lib64/ld-linux.so.2"),
2420 .sparc => if (abi == .gnu) init("/lib/ld-linux.so.2") else none,
2421 .sparc64 => if (abi == .gnu) init("/lib64/ld-linux.so.2") else none,
23492422
2350 .x86 => init("/lib/ld-linux.so.2"),
2351 .x86_64 => init(if (abi == .gnux32) "/libx32/ld-linux-x32.so.2" else "/lib64/ld-linux-x86-64.so.2"),
2423 .x86 => if (abi == .gnu) init("/lib/ld-linux.so.2") else none,
2424 .x86_64 => switch (abi) {
2425 .gnu => init("/lib64/ld-linux-x86-64.so.2"),
2426 .gnux32 => init("/libx32/ld-linux-x32.so.2"),
2427 else => none,
2428 },
23522429
2353 .xtensa => init("/lib/ld.so.1"),
2430 .xtensa => if (abi == .gnu) init("/lib/ld.so.1") else none,
23542431
2355 // These are unsupported by glibc.
2356 .amdgcn,
2357 .avr,
2358 .bpfeb,
2359 .bpfel,
2360 .hexagon,
2361 .kalimba,
2362 .lanai,
2363 .loongarch32,
2364 .msp430,
2365 .nvptx,
2366 .nvptx64,
2367 .powerpcle,
2368 .propeller1,
2369 .propeller2,
2370 .spirv,
2371 .spirv32,
2372 .spirv64,
2373 .spu_2,
2374 .ve,
2375 .wasm32,
2376 .wasm64,
2377 .xcore,
2378 => none,
2432 else => none,
23792433 }
23802434 else
23812435 none, // Not a known Linux libc.
23822436
2383 .serenity => init("/usr/lib/Loader.so"),
2437 .serenity => switch (cpu.arch) {
2438 .aarch64,
2439 .riscv64,
2440 .x86_64,
2441 => init("/usr/lib/Loader.so"),
2442 else => none,
2443 },
23842444
2385 .dragonfly => initFmt("{s}/libexec/ld-elf.so.2", .{
2445 .dragonfly => if (cpu.arch == .x86_64) initFmt("{s}/libexec/ld-elf.so.2", .{
23862446 if (os.version_range.semver.isAtLeast(.{ .major = 3, .minor = 8, .patch = 0 }) orelse false)
23872447 ""
23882448 else
23892449 "/usr",
2390 }),
2450 }) else none,
23912451
2392 .freebsd => initFmt("{s}/libexec/ld-elf.so.1", .{
2393 if (os.version_range.semver.isAtLeast(.{ .major = 6, .minor = 0, .patch = 0 }) orelse false)
2394 ""
2395 else
2396 "/usr",
2397 }),
2452 .freebsd => switch (cpu.arch) {
2453 .arm,
2454 .armeb,
2455 .thumb,
2456 .thumbeb,
2457 .aarch64,
2458 .mips,
2459 .mipsel,
2460 .mips64,
2461 .mips64el,
2462 .powerpc,
2463 .powerpc64,
2464 .powerpc64le,
2465 .riscv64,
2466 .sparc64,
2467 .x86,
2468 .x86_64,
2469 => initFmt("{s}/libexec/ld-elf.so.1", .{
2470 if (os.version_range.semver.isAtLeast(.{ .major = 6, .minor = 0, .patch = 0 }) orelse false)
2471 ""
2472 else
2473 "/usr",
2474 }),
2475 else => none,
2476 },
23982477
2399 .netbsd => init("/libexec/ld.elf_so"),
2478 .netbsd => switch (cpu.arch) {
2479 .arm,
2480 .armeb,
2481 .thumb,
2482 .thumbeb,
2483 .aarch64,
2484 .aarch64_be,
2485 .m68k,
2486 .mips,
2487 .mipsel,
2488 .mips64,
2489 .mips64el,
2490 .powerpc,
2491 .riscv64,
2492 .sparc,
2493 .sparc64,
2494 .x86,
2495 .x86_64,
2496 => init("/libexec/ld.elf_so"),
2497 else => none,
2498 },
24002499
2401 .openbsd => init("/usr/libexec/ld.so"),
2500 .openbsd => switch (cpu.arch) {
2501 .arm,
2502 .thumb,
2503 .aarch64,
2504 .mips64,
2505 .mips64el,
2506 .powerpc,
2507 .powerpc64,
2508 .riscv64,
2509 .sparc64,
2510 .x86,
2511 .x86_64,
2512 => init("/usr/libexec/ld.so"),
2513 else => none,
2514 },
24022515
2403 .bridgeos,
2516 .bridgeos => if (cpu.arch == .aarch64) init("/usr/lib/dyld") else none,
24042517 .driverkit,
24052518 .ios,
24062519 .macos,
24072520 .tvos,
24082521 .visionos,
24092522 .watchos,
2410 => init("/usr/lib/dyld"),
2523 => switch (cpu.arch) {
2524 .aarch64,
2525 .x86_64,
2526 => init("/usr/lib/dyld"),
2527 else => none,
2528 },
24112529
24122530 .illumos,
24132531 .solaris,
2414 => initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64/" else ""}),
2532 => switch (cpu.arch) {
2533 .sparc,
2534 .sparc64,
2535 .x86,
2536 .x86_64,
2537 => initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, .none) == 64) "64/" else ""}),
2538 else => none,
2539 },
24152540
24162541 // Operating systems in this list have been verified as not having a standard
24172542 // dynamic linker path.
lib/std/zig/system.zig+28-20
......@@ -967,14 +967,15 @@ fn detectAbiAndDynamicLinker(
967967 os: Target.Os,
968968 query: Target.Query,
969969) DetectError!Target {
970 const native_target_has_ld = comptime builtin.target.hasDynamicLinker();
970 const native_target_has_ld = comptime Target.DynamicLinker.kind(builtin.os.tag) != .none;
971971 const is_linux = builtin.target.os.tag == .linux;
972972 const is_solarish = builtin.target.os.tag.isSolarish();
973 const is_darwin = builtin.target.os.tag.isDarwin();
973974 const have_all_info = query.dynamic_linker.get() != null and
974975 query.abi != null and (!is_linux or query.abi.?.isGnu());
975976 const os_is_non_native = query.os_tag != null;
976977 // The Solaris/illumos environment is always the same.
977 if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) {
978 if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish or is_darwin) {
978979 return defaultAbiAndDynamicLinker(cpu, os, query);
979980 }
980981 if (query.abi) |abi| {
......@@ -999,26 +1000,33 @@ fn detectAbiAndDynamicLinker(
9991000 };
10001001 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
10011002 var ld_info_list_len: usize = 0;
1002 const ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
1003
1004 for (all_abis) |abi| {
1005 // This may be a nonsensical parameter. We detect this with
1006 // error.UnknownDynamicLinkerPath and skip adding it to `ld_info_list`.
1007 const target: Target = .{
1008 .cpu = cpu,
1009 .os = os,
1010 .abi = abi,
1011 .ofmt = ofmt,
1012 };
1013 const ld = target.standardDynamicLinkerPath();
1014 if (ld.get() == null) continue;
10151003
1016 ld_info_list_buffer[ld_info_list_len] = .{
1017 .ld = ld,
1018 .abi = abi,
1019 };
1020 ld_info_list_len += 1;
1004 switch (Target.DynamicLinker.kind(os.tag)) {
1005 // The OS has no dynamic linker. Leave the list empty and rely on `Abi.default()` to pick
1006 // something sensible in `abiAndDynamicLinkerFromFile()`.
1007 .none => {},
1008 // The OS has a system-wide dynamic linker. Unfortunately, this implies that there's no
1009 // useful ABI information that we can glean from it merely being present. That means the
1010 // best we can do for this case (for now) is also `Abi.default()`.
1011 .arch_os => {},
1012 // The OS can have different dynamic linker paths depending on libc/ABI. In this case, we
1013 // need to gather all the valid arch/OS/ABI combinations. `abiAndDynamicLinkerFromFile()`
1014 // will then look for a dynamic linker with a matching path on the system and pick the ABI
1015 // we associated it with here.
1016 .arch_os_abi => for (all_abis) |abi| {
1017 const ld = Target.DynamicLinker.standard(cpu, os, abi);
1018
1019 // Does the generated target triple actually have a standard dynamic linker path?
1020 if (ld.get() == null) continue;
1021
1022 ld_info_list_buffer[ld_info_list_len] = .{
1023 .ld = ld,
1024 .abi = abi,
1025 };
1026 ld_info_list_len += 1;
1027 },
10211028 }
1029
10221030 const ld_info_list = ld_info_list_buffer[0..ld_info_list_len];
10231031
10241032 // Best case scenario: the executable is dynamically linked, and we can iterate
test/llvm_targets.zig+7
......@@ -249,10 +249,12 @@ const targets = [_]std.Target.Query{
249249 .{ .cpu_arch = .s390x, .os_tag = .zos, .abi = .none },
250250
251251 .{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },
252 .{ .cpu_arch = .sparc, .os_tag = .illumos, .abi = .none },
252253 .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },
253254 .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .none },
254255 .{ .cpu_arch = .sparc, .os_tag = .netbsd, .abi = .none },
255256 .{ .cpu_arch = .sparc, .os_tag = .rtems, .abi = .none },
257 .{ .cpu_arch = .sparc, .os_tag = .solaris, .abi = .none },
256258
257259 .{ .cpu_arch = .sparc64, .os_tag = .freebsd, .abi = .none },
258260 .{ .cpu_arch = .sparc64, .os_tag = .freestanding, .abi = .none },
......@@ -269,6 +271,9 @@ const targets = [_]std.Target.Query{
269271 .{ .cpu_arch = .thumb, .os_tag = .freebsd, .abi = .eabihf },
270272 .{ .cpu_arch = .thumb, .os_tag = .freestanding, .abi = .eabi },
271273 .{ .cpu_arch = .thumb, .os_tag = .freestanding, .abi = .eabihf },
274 .{ .cpu_arch = .thumb, .os_tag = .haiku, .abi = .eabi },
275 .{ .cpu_arch = .thumb, .os_tag = .haiku, .abi = .eabihf },
276 .{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .androideabi },
272277 .{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .eabi },
273278 .{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .eabihf },
274279 .{ .cpu_arch = .thumb, .os_tag = .linux, .abi = .musleabi },
......@@ -314,6 +319,7 @@ const targets = [_]std.Target.Query{
314319 .{ .cpu_arch = .x86, .os_tag = .freestanding, .abi = .none },
315320 .{ .cpu_arch = .x86, .os_tag = .haiku, .abi = .none },
316321 .{ .cpu_arch = .x86, .os_tag = .hurd, .abi = .gnu },
322 .{ .cpu_arch = .x86, .os_tag = .illumos, .abi = .none },
317323 .{ .cpu_arch = .x86, .os_tag = .linux, .abi = .android },
318324 .{ .cpu_arch = .x86, .os_tag = .linux, .abi = .gnu },
319325 .{ .cpu_arch = .x86, .os_tag = .linux, .abi = .musl },
......@@ -322,6 +328,7 @@ const targets = [_]std.Target.Query{
322328 .{ .cpu_arch = .x86, .os_tag = .netbsd, .abi = .none },
323329 .{ .cpu_arch = .x86, .os_tag = .openbsd, .abi = .none },
324330 .{ .cpu_arch = .x86, .os_tag = .rtems, .abi = .none },
331 .{ .cpu_arch = .x86, .os_tag = .solaris, .abi = .none },
325332 .{ .cpu_arch = .x86, .os_tag = .uefi, .abi = .none },
326333 .{ .cpu_arch = .x86, .os_tag = .windows, .abi = .gnu },
327334 .{ .cpu_arch = .x86, .os_tag = .windows, .abi = .itanium },