Skip to content

Commit 8594f17

Browse files
authored
Merge pull request #22067 from alexrp/pie-tests
Add PIC/PIE tests and fix some bugs + some improvements to the test harness
2 parents 6cf01a6 + 5beb5f2 commit 8594f17

28 files changed

+267
-57
lines changed

build.zig

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ pub fn build(b: *std.Build) !void {
442442
test_step.dependOn(check_fmt);
443443

444444
const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
445-
try tests.addCases(b, test_cases_step, test_filters, target, .{
445+
try tests.addCases(b, test_cases_step, test_filters, test_target_filters, target, .{
446446
.skip_translate_c = skip_translate_c,
447447
.skip_run_translated_c = skip_run_translated_c,
448448
}, .{
@@ -541,13 +541,18 @@ pub fn build(b: *std.Build) !void {
541541
enable_ios_sdk,
542542
enable_symlinks_windows,
543543
));
544-
test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));
544+
test_step.dependOn(tests.addCAbiTests(b, .{
545+
.test_target_filters = test_target_filters,
546+
.skip_non_native = skip_non_native,
547+
.skip_release = skip_release,
548+
}));
545549
test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
546550
test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
547551
test_step.dependOn(tests.addCliTests(b));
548552
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
549553
if (tests.addDebuggerTests(b, .{
550554
.test_filters = test_filters,
555+
.test_target_filters = test_target_filters,
551556
.gdb = b.option([]const u8, "gdb", "path to gdb binary"),
552557
.lldb = b.option([]const u8, "lldb", "path to lldb binary"),
553558
.optimize_modes = optimization_modes,

lib/std/Build/Cache.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ pub const HashHelper = struct {
217217
},
218218
std.Target.Os.TaggedVersionRange => {
219219
switch (x) {
220+
.hurd => |hurd| {
221+
hh.add(hurd.range.min);
222+
hh.add(hurd.range.max);
223+
hh.add(hurd.glibc);
224+
},
220225
.linux => |linux| {
221226
hh.add(linux.range.min);
222227
hh.add(linux.range.max);

lib/std/Target.zig

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ pub const Os = struct {
187187
.hermit,
188188

189189
.aix,
190-
.hurd,
191190
.rtems,
192191
.zos,
193192

@@ -218,6 +217,7 @@ pub const Os = struct {
218217
.vulkan,
219218
=> .semver,
220219

220+
.hurd => .hurd,
221221
.linux => .linux,
222222

223223
.windows => .windows,
@@ -356,6 +356,21 @@ pub const Os = struct {
356356
}
357357
};
358358

359+
pub const HurdVersionRange = struct {
360+
range: std.SemanticVersion.Range,
361+
glibc: std.SemanticVersion,
362+
363+
pub inline fn includesVersion(range: HurdVersionRange, ver: std.SemanticVersion) bool {
364+
return range.range.includesVersion(ver);
365+
}
366+
367+
/// Checks if system is guaranteed to be at least `version` or older than `version`.
368+
/// Returns `null` if a runtime check is required.
369+
pub inline fn isAtLeast(range: HurdVersionRange, ver: std.SemanticVersion) ?bool {
370+
return range.range.isAtLeast(ver);
371+
}
372+
};
373+
359374
pub const LinuxVersionRange = struct {
360375
range: std.SemanticVersion.Range,
361376
glibc: std.SemanticVersion,
@@ -400,6 +415,7 @@ pub const Os = struct {
400415
pub const VersionRange = union {
401416
none: void,
402417
semver: std.SemanticVersion.Range,
418+
hurd: HurdVersionRange,
403419
linux: LinuxVersionRange,
404420
windows: WindowsVersion.Range,
405421

@@ -456,9 +472,12 @@ pub const Os = struct {
456472
},
457473
},
458474
.hurd => .{
459-
.semver = .{
460-
.min = .{ .major = 0, .minor = 9, .patch = 0 },
461-
.max = .{ .major = 0, .minor = 9, .patch = 0 },
475+
.hurd = .{
476+
.range = .{
477+
.min = .{ .major = 0, .minor = 9, .patch = 0 },
478+
.max = .{ .major = 0, .minor = 9, .patch = 0 },
479+
},
480+
.glibc = .{ .major = 2, .minor = 28, .patch = 0 },
462481
},
463482
},
464483
.linux => .{
@@ -632,8 +651,17 @@ pub const Os = struct {
632651
pub const TaggedVersionRange = union(enum) {
633652
none: void,
634653
semver: std.SemanticVersion.Range,
654+
hurd: HurdVersionRange,
635655
linux: LinuxVersionRange,
636656
windows: WindowsVersion.Range,
657+
658+
pub fn gnuLibCVersion(range: TaggedVersionRange) ?std.SemanticVersion {
659+
return switch (range) {
660+
.none, .semver, .windows => null,
661+
.hurd => |h| h.glibc,
662+
.linux => |l| l.glibc,
663+
};
664+
}
637665
};
638666

639667
/// Provides a tagged union. `Target` does not store the tag because it is
@@ -642,6 +670,7 @@ pub const Os = struct {
642670
return switch (os.tag.versionRangeTag()) {
643671
.none => .{ .none = {} },
644672
.semver => .{ .semver = os.version_range.semver },
673+
.hurd => .{ .hurd = os.version_range.hurd },
645674
.linux => .{ .linux = os.version_range.linux },
646675
.windows => .{ .windows = os.version_range.windows },
647676
};
@@ -651,12 +680,13 @@ pub const Os = struct {
651680
/// Returns `null` if a runtime check is required.
652681
pub inline fn isAtLeast(os: Os, comptime tag: Tag, ver: switch (tag.versionRangeTag()) {
653682
.none => void,
654-
.semver, .linux => std.SemanticVersion,
683+
.semver, .hurd, .linux => std.SemanticVersion,
655684
.windows => WindowsVersion,
656685
}) ?bool {
657686
return if (os.tag != tag) false else switch (tag.versionRangeTag()) {
658687
.none => true,
659688
inline .semver,
689+
.hurd,
660690
.linux,
661691
.windows,
662692
=> |field| @field(os.version_range, @tagName(field)).isAtLeast(ver),
@@ -832,6 +862,9 @@ pub const Abi = enum {
832862
.mips,
833863
.mipsel,
834864
=> .musleabi,
865+
.mips64,
866+
.mips64el,
867+
=> .muslabi64,
835868
else => .musl,
836869
},
837870
.rtems => switch (arch) {

lib/std/Target/Query.zig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub fn fromTarget(target: Target) Query {
102102
.os_version_min = undefined,
103103
.os_version_max = undefined,
104104
.abi = target.abi,
105-
.glibc_version = if (target.isGnuLibC()) target.os.version_range.linux.glibc else null,
105+
.glibc_version = target.os.versionRange().gnuLibCVersion(),
106106
.android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null,
107107
};
108108
result.updateOsVersionRange(target.os);
@@ -132,9 +132,9 @@ fn updateOsVersionRange(self: *Query, os: Target.Os) void {
132132
.{ .semver = os.version_range.semver.min },
133133
.{ .semver = os.version_range.semver.max },
134134
},
135-
.linux => .{
136-
.{ .semver = os.version_range.linux.range.min },
137-
.{ .semver = os.version_range.linux.range.max },
135+
inline .hurd, .linux => |t| .{
136+
.{ .semver = @field(os.version_range, @tagName(t)).range.min },
137+
.{ .semver = @field(os.version_range, @tagName(t)).range.max },
138138
},
139139
.windows => .{
140140
.{ .windows = os.version_range.windows.min },
@@ -544,7 +544,7 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !
544544
const version_text = it.rest();
545545
if (version_text.len > 0) switch (tag.versionRangeTag()) {
546546
.none => return error.InvalidOperatingSystemVersion,
547-
.semver, .linux => range: {
547+
.semver, .hurd, .linux => range: {
548548
var range_it = mem.splitSequence(u8, version_text, "...");
549549
result.os_version_min = .{
550550
.semver = parseVersion(range_it.first()) catch |err| switch (err) {

lib/std/c.zig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {
5656
if (!builtin.link_libc) break :blk false;
5757
if (native_abi.isMusl()) break :blk true;
5858
if (builtin.target.isGnuLibC()) {
59-
const ver = builtin.os.version_range.linux.glibc;
60-
const order = ver.order(version);
61-
break :blk switch (order) {
59+
const ver = builtin.os.versionRange().gnuLibCVersion().?;
60+
break :blk switch (ver.order(version)) {
6261
.gt, .eq => true,
6362
.lt => false,
6463
};

lib/std/os/linux/pie.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ inline fn getDynamicSymbol() [*]elf.Dyn {
178178
\\ .hidden _DYNAMIC
179179
\\ larl %[ret], 1f
180180
\\ ag %[ret], 0(%[ret])
181-
\\ b 2f
181+
\\ jg 2f
182182
\\ 1: .quad _DYNAMIC - .
183183
\\ 2:
184184
: [ret] "=r" (-> [*]elf.Dyn),

lib/std/zig/system.zig

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,24 +311,27 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
311311

312312
if (query.os_version_min) |min| switch (min) {
313313
.none => {},
314-
.semver => |semver| switch (os.tag) {
315-
.linux => os.version_range.linux.range.min = semver,
314+
.semver => |semver| switch (os.tag.versionRangeTag()) {
315+
inline .hurd, .linux => |t| @field(os.version_range, @tagName(t)).range.min = semver,
316316
else => os.version_range.semver.min = semver,
317317
},
318318
.windows => |win_ver| os.version_range.windows.min = win_ver,
319319
};
320320

321321
if (query.os_version_max) |max| switch (max) {
322322
.none => {},
323-
.semver => |semver| switch (os.tag) {
324-
.linux => os.version_range.linux.range.max = semver,
323+
.semver => |semver| switch (os.tag.versionRangeTag()) {
324+
inline .hurd, .linux => |t| @field(os.version_range, @tagName(t)).range.max = semver,
325325
else => os.version_range.semver.max = semver,
326326
},
327327
.windows => |win_ver| os.version_range.windows.max = win_ver,
328328
};
329329

330330
if (query.glibc_version) |glibc| {
331-
os.version_range.linux.glibc = glibc;
331+
switch (os.tag.versionRangeTag()) {
332+
inline .hurd, .linux => |t| @field(os.version_range, @tagName(t)).glibc = glibc,
333+
else => {},
334+
}
332335
}
333336

334337
if (query.android_api_level) |android| {

lib/std/zig/target.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ pub fn canBuildLibC(target: std.Target) bool {
8888
const ver = target.os.version_range.semver;
8989
return ver.min.order(libc.os_ver.?) != .lt;
9090
}
91-
// Ensure glibc (aka *-linux-gnu) version is supported
91+
// Ensure glibc (aka *-(linux,hurd)-gnu) version is supported
9292
if (target.isGnuLibC()) {
9393
const min_glibc_ver = libc.glibc_min orelse return true;
94-
const target_glibc_ver = target.os.version_range.linux.glibc;
94+
const target_glibc_ver = target.os.versionRange().gnuLibCVersion().?;
9595
return target_glibc_ver.order(min_glibc_ver) != .lt;
9696
}
9797
return true;

src/Builtin.zig

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,40 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
142142

143143
linux.android,
144144
}),
145+
.hurd => |hurd| try buffer.writer().print(
146+
\\ .hurd = .{{
147+
\\ .range = .{{
148+
\\ .min = .{{
149+
\\ .major = {},
150+
\\ .minor = {},
151+
\\ .patch = {},
152+
\\ }},
153+
\\ .max = .{{
154+
\\ .major = {},
155+
\\ .minor = {},
156+
\\ .patch = {},
157+
\\ }},
158+
\\ }},
159+
\\ .glibc = .{{
160+
\\ .major = {},
161+
\\ .minor = {},
162+
\\ .patch = {},
163+
\\ }},
164+
\\ }}}},
165+
\\
166+
, .{
167+
hurd.range.min.major,
168+
hurd.range.min.minor,
169+
hurd.range.min.patch,
170+
171+
hurd.range.max.major,
172+
hurd.range.max.minor,
173+
hurd.range.max.patch,
174+
175+
hurd.glibc.major,
176+
hurd.glibc.minor,
177+
hurd.glibc.patch,
178+
}),
145179
.windows => |windows| try buffer.writer().print(
146180
\\ .windows = .{{
147181
\\ .min = {c},

src/Compilation.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5315,7 +5315,7 @@ pub fn addCCArgs(
53155315

53165316
if (comp.config.link_libc) {
53175317
if (target.isGnuLibC()) {
5318-
const target_version = target.os.version_range.linux.glibc;
5318+
const target_version = target.os.versionRange().gnuLibCVersion().?;
53195319
const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{
53205320
target_version.minor,
53215321
});

src/codegen/llvm.zig

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
245245
ver.min.minor,
246246
ver.min.patch,
247247
}),
248-
.linux => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{
248+
inline .linux, .hurd => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{
249249
ver.range.min.major,
250250
ver.range.min.minor,
251251
ver.range.min.patch,
@@ -290,11 +290,15 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
290290
.semver,
291291
.windows,
292292
=> {},
293-
.linux => |ver| if (target.abi.isGnu()) try llvm_triple.writer().print("{d}.{d}.{d}", .{
294-
ver.glibc.major,
295-
ver.glibc.minor,
296-
ver.glibc.patch,
297-
}) else if (target.abi.isAndroid()) try llvm_triple.writer().print("{d}", .{ver.android}),
293+
inline .hurd, .linux => |ver| if (target.abi.isGnu()) {
294+
try llvm_triple.writer().print("{d}.{d}.{d}", .{
295+
ver.glibc.major,
296+
ver.glibc.minor,
297+
ver.glibc.patch,
298+
});
299+
} else if (@TypeOf(ver) == std.Target.Os.LinuxVersionRange and target.abi.isAndroid()) {
300+
try llvm_triple.writer().print("{d}", .{ver.android});
301+
},
298302
}
299303

300304
return llvm_triple.toOwnedSlice();

src/glibc.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
188188
const arena = arena_allocator.allocator();
189189

190190
const target = comp.root_mod.resolved_target.result;
191-
const target_ver = target.os.version_range.linux.glibc;
191+
const target_ver = target.os.versionRange().gnuLibCVersion().?;
192192
const nonshared_stat = target_ver.order(.{ .major = 2, .minor = 32, .patch = 0 }) != .gt;
193193
const start_old_init_fini = target_ver.order(.{ .major = 2, .minor = 33, .patch = 0 }) != .gt;
194194

@@ -750,7 +750,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
750750
const arena = arena_allocator.allocator();
751751

752752
const target = comp.getTarget();
753-
const target_version = target.os.version_range.linux.glibc;
753+
const target_version = target.os.versionRange().gnuLibCVersion().?;
754754

755755
// Use the global cache directory.
756756
var cache: Cache = .{
@@ -1218,7 +1218,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
12181218
}
12191219

12201220
fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
1221-
const target_version = comp.getTarget().os.version_range.linux.glibc;
1221+
const target_version = comp.getTarget().os.versionRange().gnuLibCVersion().?;
12221222

12231223
assert(comp.glibc_so_files == null);
12241224
comp.glibc_so_files = so_files;

src/libcxx.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
262262

263263
if (target.isGnuLibC()) {
264264
// glibc 2.16 introduced aligned_alloc
265-
if (target.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {
265+
if (target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {
266266
try cflags.append("-D_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION");
267267
}
268268
}
@@ -477,7 +477,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
477477
}
478478
try cflags.append("-D_LIBCXXABI_HAS_NO_THREADS");
479479
} else if (target.abi.isGnu()) {
480-
if (target.os.tag != .linux or !(target.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 18, .patch = 0 }) == .lt))
480+
if (target.os.tag != .linux or !(target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 18, .patch = 0 }) == .lt))
481481
try cflags.append("-DHAVE___CXA_THREAD_ATEXIT_IMPL");
482482
}
483483

@@ -500,7 +500,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
500500

501501
if (target.isGnuLibC()) {
502502
// glibc 2.16 introduced aligned_alloc
503-
if (target.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {
503+
if (target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {
504504
try cflags.append("-D_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION");
505505
}
506506
}

src/link/Elf.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2013,7 +2013,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
20132013
} else if (target.isGnuLibC()) {
20142014
for (glibc.libs) |lib| {
20152015
if (lib.removed_in) |rem_in| {
2016-
if (target.os.version_range.linux.glibc.order(rem_in) != .lt) continue;
2016+
if (target.os.versionRange().gnuLibCVersion().?.order(rem_in) != .lt) continue;
20172017
}
20182018

20192019
const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{

test/cases/inherit_want_safety.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ pub export fn entry() usize {
3535

3636
// compile
3737
// output_mode=Obj
38+
// emit_bin=false

0 commit comments

Comments
 (0)