authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2025-01-06 13:05:36-08:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-07 02:58:10+01:00
logfc28a71d9f019dc4ae65a363cad6330791ea928c
tree3ed2204f58b1153c724e84f9f5fa94ec1196910c
parent7aa95bc7f6bf673d69b9d9021c3cfb38b5b45f0e

Target: update the extra features before resolving the dynamic linker


1 files changed, 45 insertions(+), 45 deletions(-)

lib/std/zig/system.zig+45-45
...@@ -345,7 +345,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -345,7 +345,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
345 os.version_range.linux.android = android;345 os.version_range.linux.android = android;
346 }346 }
347347
348 const cpu = switch (query.cpu_model) {348 var cpu = switch (query.cpu_model) {
349 .native => detectNativeCpuAndFeatures(query_cpu_arch, os, query),349 .native => detectNativeCpuAndFeatures(query_cpu_arch, os, query),
350 .baseline => Target.Cpu.baseline(query_cpu_arch, os),350 .baseline => Target.Cpu.baseline(query_cpu_arch, os),
351 .determined_by_arch_os => if (query.cpu_arch == null)351 .determined_by_arch_os => if (query.cpu_arch == null)
...@@ -357,55 +357,22 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -357,55 +357,22 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
357 break :backup_cpu_detection Target.Cpu.baseline(query_cpu_arch, os);357 break :backup_cpu_detection Target.Cpu.baseline(query_cpu_arch, os);
358 };358 };
359359
360 var result = try detectAbiAndDynamicLinker(cpu, os, query);
361
362 // It's possible that we detect the native ABI, but fail to detect the OS version or were told
363 // to use the default OS version range. In that case, while we can't determine the exact native
364 // OS version, we do at least know that some ABIs require a particular OS version (by way of
365 // `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that
366 // we know is required.
367 if (result.abi != query_abi and query.os_version_min == null) {
368 const result_ver_range = &result.os.version_range;
369 const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range;
370
371 switch (result.os.tag.versionRangeTag()) {
372 .none => {},
373 .semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) {
374 result_ver_range.semver.min = abi_ver_range.semver.min;
375 },
376 inline .hurd, .linux => |t| {
377 if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) {
378 @field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min;
379 }
380
381 if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and
382 query.glibc_version == null)
383 {
384 @field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc;
385 }
386 },
387 .windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) {
388 result_ver_range.windows.min = abi_ver_range.windows.min;
389 },
390 }
391 }
392
393 // For x86, we need to populate some CPU feature flags depending on architecture360 // For x86, we need to populate some CPU feature flags depending on architecture
394 // and mode:361 // and mode:
395 // * 16bit_mode => if the abi is code16362 // * 16bit_mode => if the abi is code16
396 // * 32bit_mode => if the arch is x86363 // * 32bit_mode => if the arch is x86
397 // However, the "mode" flags can be used as overrides, so if the user explicitly364 // However, the "mode" flags can be used as overrides, so if the user explicitly
398 // sets one of them, that takes precedence.365 // sets one of them, that takes precedence.
399 switch (result.cpu.arch) {366 switch (query_cpu_arch) {
400 .x86 => {367 .x86 => {
401 if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{368 if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{
402 .@"16bit_mode", .@"32bit_mode",369 .@"16bit_mode", .@"32bit_mode",
403 })) {370 })) {
404 switch (result.abi) {371 switch (query_abi) {
405 .code16 => result.cpu.features.addFeature(372 .code16 => cpu.features.addFeature(
406 @intFromEnum(Target.x86.Feature.@"16bit_mode"),373 @intFromEnum(Target.x86.Feature.@"16bit_mode"),
407 ),374 ),
408 else => result.cpu.features.addFeature(375 else => cpu.features.addFeature(
409 @intFromEnum(Target.x86.Feature.@"32bit_mode"),376 @intFromEnum(Target.x86.Feature.@"32bit_mode"),
410 ),377 ),
411 }378 }
...@@ -416,32 +383,65 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -416,32 +383,65 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
416 // What do we do if the user specifies +thumb_mode?383 // What do we do if the user specifies +thumb_mode?
417 },384 },
418 .thumb, .thumbeb => {385 .thumb, .thumbeb => {
419 result.cpu.features.addFeature(386 cpu.features.addFeature(
420 @intFromEnum(Target.arm.Feature.thumb_mode),387 @intFromEnum(Target.arm.Feature.thumb_mode),
421 );388 );
422 },389 },
423 else => {},390 else => {},
424 }391 }
425 updateCpuFeatures(392 updateCpuFeatures(
426 &result.cpu.features,393 &cpu.features,
427 result.cpu.arch.allFeaturesList(),394 cpu.arch.allFeaturesList(),
428 query.cpu_features_add,395 query.cpu_features_add,
429 query.cpu_features_sub,396 query.cpu_features_sub,
430 );397 );
431398
432 if (result.cpu.arch == .hexagon) {399 if (cpu.arch == .hexagon) {
433 // Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature400 // Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature
434 // on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize`401 // on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize`
435 // command line parameter for the Hexagon backend to 0, so that no constants get placed in402 // command line parameter for the Hexagon backend to 0, so that no constants get placed in
436 // the SDA. (This of course breaks down if the user passes `-G <n>` to Clang...) We can't do403 // the SDA. (This of course breaks down if the user passes `-G <n>` to Clang...) We can't do
437 // the `-gpsize` hack because we can have multiple concurrent LLVM emit jobs, and command404 // the `-gpsize` hack because we can have multiple concurrent LLVM emit jobs, and command
438 // line options in LLVM are shared globally. So just force this feature off. Lovely stuff.405 // line options in LLVM are shared globally. So just force this feature off. Lovely stuff.
439 result.cpu.features.removeFeature(@intFromEnum(Target.hexagon.Feature.small_data));406 cpu.features.removeFeature(@intFromEnum(Target.hexagon.Feature.small_data));
440 }407 }
441408
442 // https://github.com/llvm/llvm-project/issues/105978409 // https://github.com/llvm/llvm-project/issues/105978
443 if (result.cpu.arch.isArm() and result.floatAbi() == .soft) {410 if (cpu.arch.isArm() and query_abi.floatAbi() == .soft) {
444 result.cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2));411 cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2));
412 }
413
414 var result = try detectAbiAndDynamicLinker(cpu, os, query);
415
416 // It's possible that we detect the native ABI, but fail to detect the OS version or were told
417 // to use the default OS version range. In that case, while we can't determine the exact native
418 // OS version, we do at least know that some ABIs require a particular OS version (by way of
419 // `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that
420 // we know is required.
421 if (result.abi != query_abi and query.os_version_min == null) {
422 const result_ver_range = &result.os.version_range;
423 const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range;
424
425 switch (result.os.tag.versionRangeTag()) {
426 .none => {},
427 .semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) {
428 result_ver_range.semver.min = abi_ver_range.semver.min;
429 },
430 inline .hurd, .linux => |t| {
431 if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) {
432 @field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min;
433 }
434
435 if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and
436 query.glibc_version == null)
437 {
438 @field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc;
439 }
440 },
441 .windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) {
442 result_ver_range.windows.min = abi_ver_range.windows.min;
443 },
444 }
445 }445 }
446446
447 return result;447 return result;