Skip to content

Commit aa6ae86

Browse files
committed
Investigate zig build test failures
1 parent 1bc4393 commit aa6ae86

6 files changed

Lines changed: 123 additions & 28 deletions

File tree

build.zig

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -845,13 +845,9 @@ fn addLibcTest(
845845
// strtol, it seems there might be some disagreement between libc-test/glibc
846846
// about how strtoul interprets negative numbers, so leaving out strtol for now
847847
inline for (.{ "argv", "basename", "clock_gettime", "string" }) |name| {
848-
const source_path = if (externalRunnerForTarget(target.result) == .darling and std.mem.eql(u8, name, "string"))
849-
"test" ++ std.fs.path.sep_str ++ "libc_test_functional_string_compat.c"
850-
else
851-
b.pathJoin(&.{ libc_test_path, "src", "functional", name ++ ".c" });
852848
const exe = addExecutableCompat(b, .{
853849
.name = "libc-test-functional-" ++ name,
854-
.root_source_file = lazyPath(b, source_path),
850+
.root_source_file = lazyPath(b, b.pathJoin(&.{ libc_test_path, "src", "functional", name ++ ".c" })),
855851
.target = target,
856852
.optimize = optimize,
857853
});

src/cstd.zig

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,8 @@ export fn _fwrite_buf(ptr: [*]const u8, size: usize, stream: *c.FILE) callconv(.
19631963

19641964
const FormatLength = enum {
19651965
none,
1966+
short,
1967+
char,
19661968
long,
19671969
long_long,
19681970
size,
@@ -2092,7 +2094,16 @@ fn vformat(out_written: *usize, writer: *FormatWriter, fmt: [*:0]const u8, args:
20922094
}
20932095

20942096
var spec_length: FormatLength = .none;
2095-
if (fmt_slice[i] == 'l') {
2097+
if (fmt_slice[i] == 'h') {
2098+
if (i + 1 < fmt_slice.len and fmt_slice[i + 1] == 'h') {
2099+
spec_length = .char;
2100+
i += 2;
2101+
} else {
2102+
spec_length = .short;
2103+
i += 1;
2104+
}
2105+
if (i >= fmt_slice.len) return false;
2106+
} else if (fmt_slice[i] == 'l') {
20962107
if (i + 1 < fmt_slice.len and fmt_slice[i + 1] == 'l') {
20972108
spec_length = .long_long;
20982109
i += 2;
@@ -2133,6 +2144,8 @@ fn vformat(out_written: *usize, writer: *FormatWriter, fmt: [*:0]const u8, args:
21332144
var buf: [100]u8 = undefined;
21342145
const len = switch (spec_length) {
21352146
.none => formatIntCompat(&buf, vaArgCompat(args, c_int), 10),
2147+
.short => formatIntCompat(&buf, @as(i16, @intCast(vaArgCompat(args, c_int))), 10),
2148+
.char => formatIntCompat(&buf, @as(i8, @intCast(vaArgCompat(args, c_int))), 10),
21362149
.long => formatIntCompat(&buf, vaArgCompat(args, c_long), 10),
21372150
.long_long => formatIntCompat(&buf, vaArgCompat(args, c_longlong), 10),
21382151
.size => formatIntCompat(&buf, vaArgCompat(args, isize), 10),
@@ -2147,6 +2160,8 @@ fn vformat(out_written: *usize, writer: *FormatWriter, fmt: [*:0]const u8, args:
21472160
var buf: [100]u8 = undefined;
21482161
const len = switch (spec_length) {
21492162
.none => formatIntCompat(&buf, vaArgCompat(args, c_uint), base),
2163+
.short => formatIntCompat(&buf, @as(u16, @intCast(vaArgCompat(args, c_uint))), base),
2164+
.char => formatIntCompat(&buf, @as(u8, @intCast(vaArgCompat(args, c_uint))), base),
21502165
.long => formatIntCompat(&buf, vaArgCompat(args, c_ulong), base),
21512166
.long_long => formatIntCompat(&buf, vaArgCompat(args, c_ulonglong), base),
21522167
.size => formatIntCompat(&buf, vaArgCompat(args, usize), base),
@@ -2155,6 +2170,18 @@ fn vformat(out_written: *usize, writer: *FormatWriter, fmt: [*:0]const u8, args:
21552170
out_written.* += written;
21562171
if (written != len) return false;
21572172
},
2173+
'p' => {
2174+
if (spec_length != .none or precision != precision_none) return false;
2175+
const ptr_value = @intFromPtr(vaArgCompat(args, ?*const anyopaque) orelse @as(?*const anyopaque, null));
2176+
var buf: [2 + (@sizeOf(usize) * 2)]u8 = undefined;
2177+
buf[0] = '0';
2178+
buf[1] = 'x';
2179+
const hex_len = formatIntCompat(buf[2..], ptr_value, 16);
2180+
const total_len = 2 + hex_len;
2181+
const written = writer.write(buf[0..total_len]);
2182+
out_written.* += written;
2183+
if (written != total_len) return false;
2184+
},
21582185
else => return false,
21592186
}
21602187

@@ -2942,9 +2969,12 @@ fn ceilCompat(x: f64) f64 {
29422969
// --------------------------------------------------------------------------------
29432970
// locale
29442971
// --------------------------------------------------------------------------------
2945-
export fn setlocale(category: c_int, locale: [*:0]const u8) callconv(.c) ?[*:0]u8 {
2972+
export fn setlocale(category: c_int, locale: ?[*:0]const u8) callconv(.c) ?[*:0]u8 {
29462973
_ = category;
2947-
const requested = std.mem.span(locale);
2974+
if (locale == null) {
2975+
return @as([*:0]u8, @ptrCast(&global.current_locale));
2976+
}
2977+
const requested = std.mem.span(locale.?);
29482978
if (requested.len == 0 or std.mem.eql(u8, requested, "C") or std.mem.eql(u8, requested, "POSIX")) {
29492979
global.current_locale[0] = 'C';
29502980
global.current_locale[1] = 0;

src/posix.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,35 @@ int fcntl(int fildes, int cmd, ...)
208208
// --------------------------------------------------------------------------------
209209
LIBCGUANA_INTERNAL int _ioctlArgPtr(int fd, unsigned long request, void *arg);
210210

211+
#if defined(__APPLE__) && defined(__aarch64__)
212+
LIBCGUANA_INTERNAL int _zdarwin_fstat64(int fd, void *buf)
213+
{
214+
register long x0 __asm("x0") = (long)fd;
215+
register void *x1 __asm("x1") = buf;
216+
unsigned int carry;
217+
218+
/*
219+
* Native Apple Silicon exposed a real ABI bug in the generic variadic
220+
* `syscall()` path for `fstat`. Keep this on a fixed-arity trap so the
221+
* kernel sees the exact register layout that libsyscall uses for
222+
* `___fstat64`.
223+
*/
224+
__asm__ volatile(
225+
"mov x16, #339\n"
226+
"svc #0x80\n"
227+
"cset %w2, cs\n"
228+
: "+r"(x0), "+r"(x1), "=r"(carry)
229+
:
230+
: "x16", "cc", "memory");
231+
232+
if (carry != 0) {
233+
errno = (int)x0;
234+
return -1;
235+
}
236+
return (int)x0;
237+
}
238+
#endif
239+
211240
int ioctl(int fd, unsigned long request, ...)
212241
{
213242
va_list args;

src/posix.zig

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const cstd = struct {
3838
oact: ?*c.struct_sigaction,
3939
) callconv(.c) c_int;
4040
extern fn __zwindows_raise_signal(sig: c_int) callconv(.c) c_int;
41+
extern fn _zdarwin_fstat64(fd: c_int, buf: *os.Stat) callconv(.c) c_int;
4142
};
4243

4344
const AtomicFlag = std.atomic.Value(u32);
@@ -157,6 +158,7 @@ const darwin_syscall = if (builtin.os.tag.isDarwin()) struct {
157158
const setitimer: c_long = 83;
158159
const getitimer: c_long = 86;
159160
const fstat: c_long = 189;
161+
const fstat64: c_long = 339;
160162
const fcntl: c_long = 92;
161163
const select: c_long = 93;
162164
const gettimeofday: c_long = 116;
@@ -3025,24 +3027,28 @@ export fn fstat(fd: c_int, buf: *c.struct_stat) c_int {
30253027
}
30263028
var stat_buf: os.Stat = undefined;
30273029
if (builtin.os.tag.isDarwin()) {
3028-
// Darwin splits here by architecture. Apple Silicon uses the native
3029-
// `fstat` syscall ABI, but Intel macOS still routes modern callers
3030-
// through the `$INODE64` userland symbol. The raw syscall fixed the
3031-
// native arm64 recursion/crash, but it returned the wrong layout under
3032-
// the x86_64 Darwin-target run. Keep the path target-authentic.
3033-
const rc = if (builtin.cpu.arch == .x86_64)
3034-
darwin.@"fstat$INODE64"(fd, &stat_buf)
3035-
else
3036-
syscall(darwin_syscall.fstat, darwinSysSigned(fd), &stat_buf);
3037-
switch (os.errno(rc)) {
3038-
.SUCCESS => {
3039-
copyPosixStatToC(buf, stat_buf);
3040-
return 0;
3041-
},
3042-
else => |e| {
3043-
c.errno = @intFromEnum(e);
3030+
// Keep Darwin on the fixed-arity libsyscall stub instead of the generic
3031+
// variadic `syscall()` bridge. Native Apple Silicon surfaced a real
3032+
// `fstat` corruption bug there that Darling did not reproduce. Apple's
3033+
// syscall maps route both macOS architectures through `___fstat64`;
3034+
// `@"fstat$INODE64"` is just the public x86_64 alias for the same stub.
3035+
if (builtin.cpu.arch == .x86_64) {
3036+
switch (os.errno(darwin.@"fstat$INODE64"(fd, &stat_buf))) {
3037+
.SUCCESS => {
3038+
copyPosixStatToC(buf, stat_buf);
3039+
return 0;
3040+
},
3041+
else => |e| {
3042+
c.errno = @intFromEnum(e);
3043+
return -1;
3044+
},
3045+
}
3046+
} else {
3047+
if (cstd._zdarwin_fstat64(fd, &stat_buf) != 0) {
30443048
return -1;
3045-
},
3049+
}
3050+
copyPosixStatToC(buf, stat_buf);
3051+
return 0;
30463052
}
30473053
}
30483054
switch (os.errno(os.system.fstat(fd, &stat_buf))) {

test/libc_parity.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,19 @@ static void read_all(FILE *stream, char *buf, size_t len)
6464
buf[n] = 0;
6565
}
6666

67-
int main(void)
67+
static void parity_system_blocks(void)
6868
{
69-
setvbuf(stdout, NULL, _IONBF, 0);
70-
7169
parity_mark("parity:block:system-null");
7270
printf("system-null:%d|", system(NULL));
7371

7472
parity_mark("parity:block:system-exit7");
7573
printf("system-exit7:%d|", system(CMD_EXIT7));
7674
parity_mark("parity:block:getenv-path");
7775
printf("getenv-path:%s|", getenv("PATH") ? getenv("PATH") : "null");
76+
}
7877

78+
static void parity_popen_blocks(void)
79+
{
7980
{
8081
parity_mark("parity:block:popen-read");
8182
FILE *p = parity_popen(CMD_PRINTF, "r");
@@ -135,14 +136,20 @@ int main(void)
135136
fclose(files[count]);
136137
}
137138
}
139+
}
138140

141+
static void parity_signal_block(void)
142+
{
139143
{
140144
parity_mark("parity:block:signal");
141145
void (*old_handler)(int) = signal(SIGINT, parity_handler);
142146
void (*prev_handler)(int) = signal(SIGINT, old_handler);
143147
printf("signal-basic:%d:%d|", old_handler != SIG_ERR, prev_handler == parity_handler);
144148
}
149+
}
145150

151+
static void parity_strto_blocks(void)
152+
{
146153
{
147154
parity_mark("parity:block:strtol");
148155
const char *s = "abc";
@@ -166,7 +173,10 @@ int main(void)
166173
dist = (long)(endptr - s);
167174
printf("strtod-nodigits:%d:%d:%ld|", value == 0.0, errno, dist);
168175
}
176+
}
169177

178+
static void parity_signal_api_blocks(void)
179+
{
170180
#if LIBC_PARITY_HAVE_STRSIGNAL
171181
{
172182
const char *name = strsignal(SIGINT);
@@ -197,7 +207,10 @@ int main(void)
197207
#else
198208
printf("sigaction-basic:skip|");
199209
#endif
210+
}
200211

212+
static void parity_time_blocks(void)
213+
{
201214
#if LIBC_PARITY_HAVE_SETITIMER
202215
{
203216
struct itimerval val;
@@ -234,7 +247,10 @@ int main(void)
234247
#else
235248
printf("pselect-timeout:skip|");
236249
#endif
250+
}
237251

252+
static void parity_utimes_block(void)
253+
{
238254
#if LIBC_PARITY_HAVE_UTIMES
239255
{
240256
parity_mark("parity:block:utimes");
@@ -263,7 +279,10 @@ int main(void)
263279
#else
264280
printf("utimes-basic:skip|");
265281
#endif
282+
}
266283

284+
static void parity_posix_io_blocks(void)
285+
{
267286
#if LIBC_PARITY_HAVE_POSIX_IO
268287
{
269288
parity_mark("parity:block:gethostname");
@@ -382,6 +401,20 @@ int main(void)
382401
#else
383402
printf("gethostname:skip|openat-size:skip|link-basic:skip|fcntl-basic:skip|writev-basic:skip|pathconf-basic:skip|");
384403
#endif
404+
}
405+
406+
int main(void)
407+
{
408+
setvbuf(stdout, NULL, _IONBF, 0);
409+
410+
parity_system_blocks();
411+
parity_popen_blocks();
412+
parity_signal_block();
413+
parity_strto_blocks();
414+
parity_signal_api_blocks();
415+
parity_time_blocks();
416+
parity_utimes_block();
417+
parity_posix_io_blocks();
385418

386419
return 0;
387420
}

test/panic_replacements.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ int main(int argc, char *argv[])
3636
}
3737

3838
expect(NULL != setlocale(LC_ALL, "C"));
39+
expect(0 == strcmp("C", setlocale(LC_ALL, NULL)));
3940
expect(0 == strcmp("C", setlocale(LC_ALL, "")));
4041
expect(NULL == setlocale(LC_ALL, "en_US.UTF-8"));
4142

0 commit comments

Comments
 (0)