aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-09-23 15:21:40 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-09-23 15:21:40 -0700
commit64deb46859a11588fb97e8464ec9dae53124b96b (patch)
treed58a5e1e8a5f0f6dfd5c9e6679767e4b82a2a3a5 /src
parent90b320d0e90c4daa5dcad6248623a69b3f7f2ab1 (diff)
downloadzig-64deb46859a11588fb97e8464ec9dae53124b96b.tar.gz
zig-64deb46859a11588fb97e8464ec9dae53124b96b.zip
stage2: capture LLD stderr into a buffer
Diffstat (limited to 'src')
-rw-r--r--src/link/Elf.zig41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index d4900ccb25..88255b5280 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1591,9 +1591,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
new_argv[i] = try arena.dupeZ(u8, arg);
}
+ var stderr_context: LLDContext = .{
+ .elf = self,
+ .data = std.ArrayList(u8).init(self.base.allocator),
+ };
+ defer stderr_context.data.deinit();
+ var stdout_context: LLDContext = .{
+ .elf = self,
+ .data = std.ArrayList(u8).init(self.base.allocator),
+ };
+ defer stdout_context.data.deinit();
const llvm = @import("../llvm.zig");
- const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0);
- if (!ok) return error.LLDReportedFailure;
+ const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic,
+ @ptrToInt(&stdout_context),
+ @ptrToInt(&stderr_context),
+ );
+ if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
+ if (stdout_context.data.items.len != 0) {
+ std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
+ }
+ if (!ok) {
+ // TODO parse this output and surface with the Compilation API rather than
+ // directly outputting to stderr here.
+ std.debug.print("{}", .{stderr_context.data.items});
+ return error.LLDReportedFailure;
+ }
+ if (stderr_context.data.items.len != 0) {
+ std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
+ }
// Update the dangling symlink with the digest. If it fails we can continue; it only
// means that the next invocation will have an unnecessary cache miss.
@@ -1609,10 +1634,18 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
self.base.lock = ch.toOwnedLock();
}
+const LLDContext = struct {
+ data: std.ArrayList(u8),
+ elf: *Elf,
+ oom: bool = false,
+};
+
fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void {
- // TODO collect diagnostics and handle cleanly
+ const lld_context = @intToPtr(*LLDContext, context);
const msg = ptr[0..len];
- std.log.err("LLD: {}", .{msg});
+ lld_context.data.appendSlice(msg) catch |err| switch (err) {
+ error.OutOfMemory => lld_context.oom = true,
+ };
}
fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void {