authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-23 15:21:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-23 15:21:40-07:00
log64deb46859a11588fb97e8464ec9dae53124b96b
treed58a5e1e8a5f0f6dfd5c9e6679767e4b82a2a3a5
parent90b320d0e90c4daa5dcad6248623a69b3f7f2ab1

stage2: capture LLD stderr into a buffer


2 files changed, 39 insertions(+), 6 deletions(-)

BRANCH_TODO+2-2
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1 * musl1 * musl
2 * implement proper parsing of LLD stderr/stdout and exposing compile errors
3 * tests passing with -Dskip-non-native2 * tests passing with -Dskip-non-native
4 * windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj]3 * windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj]
5 * repair @cImport4 * repair @cImport
...@@ -23,10 +22,11 @@...@@ -23,10 +22,11 @@
23 (maybe make it an explicit option and have main.zig disable it)22 (maybe make it an explicit option and have main.zig disable it)
24 * audit the CLI options for stage223 * audit the CLI options for stage2
25 * audit the base cache hash24 * audit the base cache hash
26 * implement proper parsing of clang stderr/stdout and exposing compile errors
27 * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.25 * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.
28 * restore error messages for stage2_add_link_lib26 * restore error messages for stage2_add_link_lib
2927
28 * implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API
29 * implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API
30 * support cross compiling stage2 with `zig build`30 * support cross compiling stage2 with `zig build`
31 * implement proper compile errors for failing to build glibc crt files and shared libs31 * implement proper compile errors for failing to build glibc crt files and shared libs
32 * implement -fno-emit-bin32 * implement -fno-emit-bin
src/link/Elf.zig+37-4
...@@ -1591,9 +1591,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1591,9 +1591,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1591 new_argv[i] = try arena.dupeZ(u8, arg);1591 new_argv[i] = try arena.dupeZ(u8, arg);
1592 }1592 }
15931593
1594 var stderr_context: LLDContext = .{
1595 .elf = self,
1596 .data = std.ArrayList(u8).init(self.base.allocator),
1597 };
1598 defer stderr_context.data.deinit();
1599 var stdout_context: LLDContext = .{
1600 .elf = self,
1601 .data = std.ArrayList(u8).init(self.base.allocator),
1602 };
1603 defer stdout_context.data.deinit();
1594 const llvm = @import("../llvm.zig");1604 const llvm = @import("../llvm.zig");
1595 const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0);1605 const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic,
1596 if (!ok) return error.LLDReportedFailure;1606 @ptrToInt(&stdout_context),
1607 @ptrToInt(&stderr_context),
1608 );
1609 if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
1610 if (stdout_context.data.items.len != 0) {
1611 std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
1612 }
1613 if (!ok) {
1614 // TODO parse this output and surface with the Compilation API rather than
1615 // directly outputting to stderr here.
1616 std.debug.print("{}", .{stderr_context.data.items});
1617 return error.LLDReportedFailure;
1618 }
1619 if (stderr_context.data.items.len != 0) {
1620 std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
1621 }
15971622
1598 // Update the dangling symlink with the digest. If it fails we can continue; it only1623 // Update the dangling symlink with the digest. If it fails we can continue; it only
1599 // means that the next invocation will have an unnecessary cache miss.1624 // means that the next invocation will have an unnecessary cache miss.
...@@ -1609,10 +1634,18 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1609,10 +1634,18 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1609 self.base.lock = ch.toOwnedLock();1634 self.base.lock = ch.toOwnedLock();
1610}1635}
16111636
1637const LLDContext = struct {
1638 data: std.ArrayList(u8),
1639 elf: *Elf,
1640 oom: bool = false,
1641};
1642
1612fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void {1643fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void {
1613 // TODO collect diagnostics and handle cleanly1644 const lld_context = @intToPtr(*LLDContext, context);
1614 const msg = ptr[0..len];1645 const msg = ptr[0..len];
1615 std.log.err("LLD: {}", .{msg});1646 lld_context.data.appendSlice(msg) catch |err| switch (err) {
1647 error.OutOfMemory => lld_context.oom = true,
1648 };
1616}1649}
16171650
1618fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void {1651fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void {