Skip to content

Commit

Permalink
Use length field as passed in stage2 libc_installation instead of rel…
Browse files Browse the repository at this point in the history
…ying on zero termination
  • Loading branch information
daurnimator committed Mar 31, 2020
1 parent e3835e5 commit 775d89a
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 65 deletions.
101 changes: 62 additions & 39 deletions src-self-hosted/libc_installation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ usingnamespace @import("windows_sdk.zig");

/// See the render function implementation for documentation of the fields.
pub const LibCInstallation = struct {
include_dir: ?[:0]const u8 = null,
sys_include_dir: ?[:0]const u8 = null,
crt_dir: ?[:0]const u8 = null,
msvc_lib_dir: ?[:0]const u8 = null,
kernel32_lib_dir: ?[:0]const u8 = null,
include_dir: ?[]const u8 = null,
sys_include_dir: ?[]const u8 = null,
crt_dir: ?[]const u8 = null,
msvc_lib_dir: ?[]const u8 = null,
kernel32_lib_dir: ?[]const u8 = null,

pub const FindError = error{
OutOfMemory,
Expand Down Expand Up @@ -327,15 +327,20 @@ pub const LibCInstallation = struct {
var search_buf: [2]Search = undefined;
const searches = fillSearch(&search_buf, sdk);

var result_buf = try std.Buffer.initSize(allocator, 0);
defer result_buf.deinit();

for (searches) |search| {
result_buf.shrink(0);
const stream = result_buf.outStream();
try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });

var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
const dir_path = try fs.path.join(
allocator,
&[_][]const u8{
search.path,
"Include",
search.version,
"ucrt",
},
);
var found = false;
defer if (!found) allocator.free(dir_path);

const dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
error.FileNotFound,
error.NotDir,
error.NoDevice,
Expand All @@ -350,7 +355,8 @@ pub const LibCInstallation = struct {
else => return error.FileSystem,
};

self.include_dir = result_buf.toOwnedSlice();
found = true;
self.include_dir = dir_path;
return;
}

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

var result_buf = try std.Buffer.initSize(allocator, 0);
defer result_buf.deinit();

const arch_sub_dir = switch (builtin.arch) {
.i386 => "x86",
.x86_64 => "x64",
Expand All @@ -378,11 +381,20 @@ pub const LibCInstallation = struct {
};

for (searches) |search| {
result_buf.shrink(0);
const stream = result_buf.outStream();
try stream.print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });

var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
const dir_path = try fs.path.join(
allocator,
&[_][]const u8{
search.path,
"Lib",
search.version,
"ucrt",
arch_sub_dir,
},
);
var found = false;
defer if (!found) allocator.free(dir_path);

var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
error.FileNotFound,
error.NotDir,
error.NoDevice,
Expand All @@ -397,7 +409,8 @@ pub const LibCInstallation = struct {
else => return error.FileSystem,
};

self.crt_dir = result_buf.toOwnedSlice();
found = true;
self.crt_dir = dir_path;
return;
}
return error.LibCRuntimeNotFound;
Expand All @@ -421,10 +434,6 @@ pub const LibCInstallation = struct {

var search_buf: [2]Search = undefined;
const searches = fillSearch(&search_buf, sdk);

var result_buf = try std.Buffer.initSize(allocator, 0);
defer result_buf.deinit();

const arch_sub_dir = switch (builtin.arch) {
.i386 => "x86",
.x86_64 => "x64",
Expand All @@ -433,11 +442,20 @@ pub const LibCInstallation = struct {
};

for (searches) |search| {
result_buf.shrink(0);
const stream = result_buf.outStream();
try stream.print("{}\\Lib\\{}\\um\\{}", .{ search.path, search.version, arch_sub_dir });

var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
const dir_path = try fs.path.join(
allocator,
&[_][]const u8{
search.path,
"Lib",
search.version,
"um",
arch_sub_dir,
},
);
var found = false;
defer if (!found) allocator.free(dir_path);

var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
error.FileNotFound,
error.NotDir,
error.NoDevice,
Expand All @@ -452,7 +470,8 @@ pub const LibCInstallation = struct {
else => return error.FileSystem,
};

self.kernel32_lib_dir = result_buf.toOwnedSlice();
found = true;
self.kernel32_lib_dir = dir_path;
return;
}
return error.LibCKernel32LibNotFound;
Expand All @@ -470,12 +489,16 @@ pub const LibCInstallation = struct {
const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;

var result_buf = try std.Buffer.init(allocator, up2);
defer result_buf.deinit();

try result_buf.append("\\include");
const dir_path = try fs.path.join(
allocator,
&[_][]const u8{
up2,
"include",
},
);
errdefer allocator.free(dir_path);

var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
error.FileNotFound,
error.NotDir,
error.NoDevice,
Expand All @@ -490,7 +513,7 @@ pub const LibCInstallation = struct {
else => return error.FileSystem,
};

self.sys_include_dir = result_buf.toOwnedSlice();
self.sys_include_dir = dir_path;
}

fn findNativeMsvcLibDir(
Expand Down
20 changes: 10 additions & 10 deletions src-self-hosted/stage2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -742,15 +742,15 @@ fn stage2TargetParse(

// ABI warning
const Stage2LibCInstallation = extern struct {
include_dir: [*:0]const u8,
include_dir: [*]const u8,
include_dir_len: usize,
sys_include_dir: [*:0]const u8,
sys_include_dir: [*]const u8,
sys_include_dir_len: usize,
crt_dir: [*:0]const u8,
crt_dir: [*]const u8,
crt_dir_len: usize,
msvc_lib_dir: [*:0]const u8,
msvc_lib_dir: [*]const u8,
msvc_lib_dir_len: usize,
kernel32_lib_dir: [*:0]const u8,
kernel32_lib_dir: [*]const u8,
kernel32_lib_dir_len: usize,

fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
Expand Down Expand Up @@ -794,19 +794,19 @@ const Stage2LibCInstallation = extern struct {
fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
var libc: LibCInstallation = .{};
if (self.include_dir_len != 0) {
libc.include_dir = self.include_dir[0..self.include_dir_len :0];
libc.include_dir = self.include_dir[0..self.include_dir_len];
}
if (self.sys_include_dir_len != 0) {
libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0];
libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len];
}
if (self.crt_dir_len != 0) {
libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0];
libc.crt_dir = self.crt_dir[0..self.crt_dir_len];
}
if (self.msvc_lib_dir_len != 0) {
libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0];
libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len];
}
if (self.kernel32_lib_dir_len != 0) {
libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0];
libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len];
}
return libc;
}
Expand Down
8 changes: 7 additions & 1 deletion src/cache_hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,17 @@ void cache_init(CacheHash *ch, Buf *manifest_dir) {
void cache_mem(CacheHash *ch, const char *ptr, size_t len) {
assert(ch->manifest_file_path == nullptr);
assert(ptr != nullptr);
// + 1 to include the null byte
blake2b_update(&ch->blake, ptr, len);
}

void cache_slice(CacheHash *ch, Slice<const char> slice) {
// mix the length into the hash so that two juxtaposed cached slices can't collide
cache_usize(slice.len);
cache_mem(ch, slice.ptr, slice.len);
}

void cache_str(CacheHash *ch, const char *ptr) {
// + 1 to include the null byte
cache_mem(ch, ptr, strlen(ptr) + 1);
}

Expand Down
1 change: 1 addition & 0 deletions src/cache_hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);

// Next, use the hash population functions to add the initial parameters.
void cache_mem(CacheHash *ch, const char *ptr, size_t len);
void cache_slice(CacheHash *ch, Slice<const char> slice);
void cache_str(CacheHash *ch, const char *ptr);
void cache_int(CacheHash *ch, int x);
void cache_bool(CacheHash *ch, bool x);
Expand Down
27 changes: 16 additions & 11 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9123,21 +9123,26 @@ static void detect_libc(CodeGen *g) {
g->libc_include_dir_len = 0;
g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);

g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir;
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));
g->libc_include_dir_len += 1;

if (want_sys_dir) {
g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir;
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));
g->libc_include_dir_len += 1;
}

if (want_um_and_shared_dirs != 0) {
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
"%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));
Buf *include_dir_parent = buf_alloc();
os_path_join(buf_create_from_mem(g->libc->include_dir, g->libc->include_dir_len), buf_create_from_str(".."), include_dir_parent);

Buf *buff1 = buf_alloc();
os_path_join(include_dir_parent, buf_create_from_str("um"), buff1);
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff1);
g->libc_include_dir_len += 1;

g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
"%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));
Buf *buff2 = buf_alloc();
os_path_join(include_dir_parent, buf_create_from_str("shared"), buff2);
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff2);
g->libc_include_dir_len += 1;
}
assert(g->libc_include_dir_len == dir_count);
Expand Down Expand Up @@ -10546,11 +10551,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
if (g->libc) {
cache_str(ch, g->libc->include_dir);
cache_str(ch, g->libc->sys_include_dir);
cache_str(ch, g->libc->crt_dir);
cache_str(ch, g->libc->msvc_lib_dir);
cache_str(ch, g->libc->kernel32_lib_dir);
cache_slice(ch, Slice<const char>{g->libc->include_dir, g->libc->include_dir_len});
cache_slice(ch, Slice<const char>{g->libc->sys_include_dir, g->libc->sys_include_dir_len});
cache_slice(ch, Slice<const char>{g->libc->crt_dir, g->libc->crt_dir_len});
cache_slice(ch, Slice<const char>{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len});
cache_slice(ch, Slice<const char>{g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len});
}
cache_buf_opt(ch, g->version_script_path);
cache_buf_opt(ch, g->override_soname);
Expand Down
18 changes: 14 additions & 4 deletions src/link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2383,11 +2383,21 @@ static void construct_linker_job_coff(LinkJob *lj) {
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));

if (target_abi_is_gnu(g->zig_target->abi)) {
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->sys_include_dir)));
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->include_dir)));
Buf *buff1 = buf_create_from_str("-LIBPATH:");
buf_append_mem(buff, g->libc->sys_include_dir, g->libc->sys_include_dir_len);
lj->args.append(buf_ptr(buff1));

Buf *buff2 = buf_create_from_str("-LIBPATH:");
buf_append_mem(buff, g->libc->include_dir, g->libc->include_dir_len);
lj->args.append(buf_ptr(buff2));
} else {
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->msvc_lib_dir)));
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->kernel32_lib_dir)));
Buf *buff1 = buf_create_from_str("-LIBPATH:");
buf_append_mem(buff1, g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len);
lj->args.append(buf_ptr(buff1));

Buf *buff2 = buf_create_from_str("-LIBPATH:");
buf_append_mem(buff2, g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len);
lj->args.append(buf_ptr(buff2));
}
}

Expand Down

0 comments on commit 775d89a

Please sign in to comment.