Skip to content

Commit 14fb7d2

Browse files
committed
Use length field as passed in stage2 libc_installation instead of relying on zero termination
1 parent e3835e5 commit 14fb7d2

File tree

6 files changed

+115
-68
lines changed

6 files changed

+115
-68
lines changed

src-self-hosted/libc_installation.zig

+62-39
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ usingnamespace @import("windows_sdk.zig");
1414

1515
/// See the render function implementation for documentation of the fields.
1616
pub const LibCInstallation = struct {
17-
include_dir: ?[:0]const u8 = null,
18-
sys_include_dir: ?[:0]const u8 = null,
19-
crt_dir: ?[:0]const u8 = null,
20-
msvc_lib_dir: ?[:0]const u8 = null,
21-
kernel32_lib_dir: ?[:0]const u8 = null,
17+
include_dir: ?[]const u8 = null,
18+
sys_include_dir: ?[]const u8 = null,
19+
crt_dir: ?[]const u8 = null,
20+
msvc_lib_dir: ?[]const u8 = null,
21+
kernel32_lib_dir: ?[]const u8 = null,
2222

2323
pub const FindError = error{
2424
OutOfMemory,
@@ -327,15 +327,20 @@ pub const LibCInstallation = struct {
327327
var search_buf: [2]Search = undefined;
328328
const searches = fillSearch(&search_buf, sdk);
329329

330-
var result_buf = try std.Buffer.initSize(allocator, 0);
331-
defer result_buf.deinit();
332-
333330
for (searches) |search| {
334-
result_buf.shrink(0);
335-
const stream = result_buf.outStream();
336-
try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
337-
338-
var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
331+
const dir_path = try fs.path.join(
332+
allocator,
333+
&[_][]const u8{
334+
search.path,
335+
"Include",
336+
search.version,
337+
"ucrt",
338+
},
339+
);
340+
var found = false;
341+
defer if (!found) allocator.free(dir_path);
342+
343+
var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
339344
error.FileNotFound,
340345
error.NotDir,
341346
error.NoDevice,
@@ -350,7 +355,8 @@ pub const LibCInstallation = struct {
350355
else => return error.FileSystem,
351356
};
352357

353-
self.include_dir = result_buf.toOwnedSlice();
358+
found = true;
359+
self.include_dir = dir_path;
354360
return;
355361
}
356362

@@ -367,9 +373,6 @@ pub const LibCInstallation = struct {
367373
var search_buf: [2]Search = undefined;
368374
const searches = fillSearch(&search_buf, sdk);
369375

370-
var result_buf = try std.Buffer.initSize(allocator, 0);
371-
defer result_buf.deinit();
372-
373376
const arch_sub_dir = switch (builtin.arch) {
374377
.i386 => "x86",
375378
.x86_64 => "x64",
@@ -378,11 +381,20 @@ pub const LibCInstallation = struct {
378381
};
379382

380383
for (searches) |search| {
381-
result_buf.shrink(0);
382-
const stream = result_buf.outStream();
383-
try stream.print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
384-
385-
var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
384+
const dir_path = try fs.path.join(
385+
allocator,
386+
&[_][]const u8{
387+
search.path,
388+
"Lib",
389+
search.version,
390+
"ucrt",
391+
arch_sub_dir,
392+
},
393+
);
394+
var found = false;
395+
defer if (!found) allocator.free(dir_path);
396+
397+
var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
386398
error.FileNotFound,
387399
error.NotDir,
388400
error.NoDevice,
@@ -397,7 +409,8 @@ pub const LibCInstallation = struct {
397409
else => return error.FileSystem,
398410
};
399411

400-
self.crt_dir = result_buf.toOwnedSlice();
412+
found = true;
413+
self.crt_dir = dir_path;
401414
return;
402415
}
403416
return error.LibCRuntimeNotFound;
@@ -421,10 +434,6 @@ pub const LibCInstallation = struct {
421434

422435
var search_buf: [2]Search = undefined;
423436
const searches = fillSearch(&search_buf, sdk);
424-
425-
var result_buf = try std.Buffer.initSize(allocator, 0);
426-
defer result_buf.deinit();
427-
428437
const arch_sub_dir = switch (builtin.arch) {
429438
.i386 => "x86",
430439
.x86_64 => "x64",
@@ -433,11 +442,20 @@ pub const LibCInstallation = struct {
433442
};
434443

435444
for (searches) |search| {
436-
result_buf.shrink(0);
437-
const stream = result_buf.outStream();
438-
try stream.print("{}\\Lib\\{}\\um\\{}", .{ search.path, search.version, arch_sub_dir });
439-
440-
var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
445+
const dir_path = try fs.path.join(
446+
allocator,
447+
&[_][]const u8{
448+
search.path,
449+
"Lib",
450+
search.version,
451+
"um",
452+
arch_sub_dir,
453+
},
454+
);
455+
var found = false;
456+
defer if (!found) allocator.free(dir_path);
457+
458+
var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
441459
error.FileNotFound,
442460
error.NotDir,
443461
error.NoDevice,
@@ -452,7 +470,8 @@ pub const LibCInstallation = struct {
452470
else => return error.FileSystem,
453471
};
454472

455-
self.kernel32_lib_dir = result_buf.toOwnedSlice();
473+
found = true;
474+
self.kernel32_lib_dir = dir_path;
456475
return;
457476
}
458477
return error.LibCKernel32LibNotFound;
@@ -470,12 +489,16 @@ pub const LibCInstallation = struct {
470489
const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
471490
const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
472491

473-
var result_buf = try std.Buffer.init(allocator, up2);
474-
defer result_buf.deinit();
475-
476-
try result_buf.append("\\include");
492+
const dir_path = try fs.path.join(
493+
allocator,
494+
&[_][]const u8{
495+
up2,
496+
"include",
497+
},
498+
);
499+
errdefer allocator.free(dir_path);
477500

478-
var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
501+
var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
479502
error.FileNotFound,
480503
error.NotDir,
481504
error.NoDevice,
@@ -490,7 +513,7 @@ pub const LibCInstallation = struct {
490513
else => return error.FileSystem,
491514
};
492515

493-
self.sys_include_dir = result_buf.toOwnedSlice();
516+
self.sys_include_dir = dir_path;
494517
}
495518

496519
fn findNativeMsvcLibDir(

src-self-hosted/stage2.zig

+10-10
Original file line numberDiff line numberDiff line change
@@ -742,15 +742,15 @@ fn stage2TargetParse(
742742

743743
// ABI warning
744744
const Stage2LibCInstallation = extern struct {
745-
include_dir: [*:0]const u8,
745+
include_dir: [*]const u8,
746746
include_dir_len: usize,
747-
sys_include_dir: [*:0]const u8,
747+
sys_include_dir: [*]const u8,
748748
sys_include_dir_len: usize,
749-
crt_dir: [*:0]const u8,
749+
crt_dir: [*]const u8,
750750
crt_dir_len: usize,
751-
msvc_lib_dir: [*:0]const u8,
751+
msvc_lib_dir: [*]const u8,
752752
msvc_lib_dir_len: usize,
753-
kernel32_lib_dir: [*:0]const u8,
753+
kernel32_lib_dir: [*]const u8,
754754
kernel32_lib_dir_len: usize,
755755

756756
fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
@@ -794,19 +794,19 @@ const Stage2LibCInstallation = extern struct {
794794
fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
795795
var libc: LibCInstallation = .{};
796796
if (self.include_dir_len != 0) {
797-
libc.include_dir = self.include_dir[0..self.include_dir_len :0];
797+
libc.include_dir = self.include_dir[0..self.include_dir_len];
798798
}
799799
if (self.sys_include_dir_len != 0) {
800-
libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0];
800+
libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len];
801801
}
802802
if (self.crt_dir_len != 0) {
803-
libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0];
803+
libc.crt_dir = self.crt_dir[0..self.crt_dir_len];
804804
}
805805
if (self.msvc_lib_dir_len != 0) {
806-
libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0];
806+
libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len];
807807
}
808808
if (self.kernel32_lib_dir_len != 0) {
809-
libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0];
809+
libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len];
810810
}
811811
return libc;
812812
}

src/cache_hash.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@ void cache_init(CacheHash *ch, Buf *manifest_dir) {
2727
void cache_mem(CacheHash *ch, const char *ptr, size_t len) {
2828
assert(ch->manifest_file_path == nullptr);
2929
assert(ptr != nullptr);
30-
// + 1 to include the null byte
3130
blake2b_update(&ch->blake, ptr, len);
3231
}
3332

33+
void cache_slice(CacheHash *ch, Slice<const char> slice) {
34+
// mix the length into the hash so that two juxtaposed cached slices can't collide
35+
cache_usize(ch, slice.len);
36+
cache_mem(ch, slice.ptr, slice.len);
37+
}
38+
3439
void cache_str(CacheHash *ch, const char *ptr) {
40+
// + 1 to include the null byte
3541
cache_mem(ch, ptr, strlen(ptr) + 1);
3642
}
3743

src/cache_hash.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);
3636

3737
// Next, use the hash population functions to add the initial parameters.
3838
void cache_mem(CacheHash *ch, const char *ptr, size_t len);
39+
void cache_slice(CacheHash *ch, Slice<const char> slice);
3940
void cache_str(CacheHash *ch, const char *ptr);
4041
void cache_int(CacheHash *ch, int x);
4142
void cache_bool(CacheHash *ch, bool x);

src/codegen.cpp

+16-11
Original file line numberDiff line numberDiff line change
@@ -9123,21 +9123,26 @@ static void detect_libc(CodeGen *g) {
91239123
g->libc_include_dir_len = 0;
91249124
g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);
91259125

9126-
g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir;
9126+
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(g->libc->include_dir, g->libc->include_dir_len));
91279127
g->libc_include_dir_len += 1;
91289128

91299129
if (want_sys_dir) {
9130-
g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir;
9130+
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(g->libc->sys_include_dir, g->libc->sys_include_dir_len));
91319131
g->libc_include_dir_len += 1;
91329132
}
91339133

91349134
if (want_um_and_shared_dirs != 0) {
9135-
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
9136-
"%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));
9135+
Buf *include_dir_parent = buf_alloc();
9136+
os_path_join(buf_create_from_mem(g->libc->include_dir, g->libc->include_dir_len), buf_create_from_str(".."), include_dir_parent);
9137+
9138+
Buf *buff1 = buf_alloc();
9139+
os_path_join(include_dir_parent, buf_create_from_str("um"), buff1);
9140+
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff1);
91379141
g->libc_include_dir_len += 1;
91389142

9139-
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
9140-
"%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));
9143+
Buf *buff2 = buf_alloc();
9144+
os_path_join(include_dir_parent, buf_create_from_str("shared"), buff2);
9145+
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff2);
91419146
g->libc_include_dir_len += 1;
91429147
}
91439148
assert(g->libc_include_dir_len == dir_count);
@@ -10546,11 +10551,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1054610551
cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
1054710552
cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
1054810553
if (g->libc) {
10549-
cache_str(ch, g->libc->include_dir);
10550-
cache_str(ch, g->libc->sys_include_dir);
10551-
cache_str(ch, g->libc->crt_dir);
10552-
cache_str(ch, g->libc->msvc_lib_dir);
10553-
cache_str(ch, g->libc->kernel32_lib_dir);
10554+
cache_slice(ch, Slice<const char>{g->libc->include_dir, g->libc->include_dir_len});
10555+
cache_slice(ch, Slice<const char>{g->libc->sys_include_dir, g->libc->sys_include_dir_len});
10556+
cache_slice(ch, Slice<const char>{g->libc->crt_dir, g->libc->crt_dir_len});
10557+
cache_slice(ch, Slice<const char>{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len});
10558+
cache_slice(ch, Slice<const char>{g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len});
1055410559
}
1055510560
cache_buf_opt(ch, g->version_script_path);
1055610561
cache_buf_opt(ch, g->override_soname);

src/link.cpp

+19-7
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
15941594
} else {
15951595
assert(parent->libc != nullptr);
15961596
Buf *out_buf = buf_alloc();
1597-
os_path_join(buf_create_from_str(parent->libc->crt_dir), buf_create_from_str(file), out_buf);
1597+
os_path_join(buf_create_from_mem(parent->libc->crt_dir, parent->libc->crt_dir_len), buf_create_from_str(file), out_buf);
15981598
return buf_ptr(out_buf);
15991599
}
16001600
}
@@ -1859,7 +1859,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
18591859
if (g->libc_link_lib != nullptr) {
18601860
if (g->libc != nullptr) {
18611861
lj->args.append("-L");
1862-
lj->args.append(g->libc->crt_dir);
1862+
lj->args.append(buf_ptr(buf_create_from_mem(g->libc->crt_dir, g->libc->crt_dir_len)));
18631863
}
18641864

18651865
if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
@@ -2380,14 +2380,26 @@ static void construct_linker_job_coff(LinkJob *lj) {
23802380
lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
23812381

23822382
if (g->libc_link_lib != nullptr && g->libc != nullptr) {
2383-
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));
2383+
Buf *buff0 = buf_create_from_str("-LIBPATH:");
2384+
buf_append_mem(buff0, g->libc->crt_dir, g->libc->crt_dir_len);
2385+
lj->args.append(buf_ptr(buff0));
23842386

23852387
if (target_abi_is_gnu(g->zig_target->abi)) {
2386-
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->sys_include_dir)));
2387-
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->include_dir)));
2388+
Buf *buff1 = buf_create_from_str("-LIBPATH:");
2389+
buf_append_mem(buff1, g->libc->sys_include_dir, g->libc->sys_include_dir_len);
2390+
lj->args.append(buf_ptr(buff1));
2391+
2392+
Buf *buff2 = buf_create_from_str("-LIBPATH:");
2393+
buf_append_mem(buff2, g->libc->include_dir, g->libc->include_dir_len);
2394+
lj->args.append(buf_ptr(buff2));
23882395
} else {
2389-
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->msvc_lib_dir)));
2390-
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->kernel32_lib_dir)));
2396+
Buf *buff1 = buf_create_from_str("-LIBPATH:");
2397+
buf_append_mem(buff1, g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len);
2398+
lj->args.append(buf_ptr(buff1));
2399+
2400+
Buf *buff2 = buf_create_from_str("-LIBPATH:");
2401+
buf_append_mem(buff2, g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len);
2402+
lj->args.append(buf_ptr(buff2));
23912403
}
23922404
}
23932405

0 commit comments

Comments
 (0)