| ... | @@ -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 | } |
| 1593 | | 1593 | |
| | 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 | } |
| 1597 | | 1622 | |
| 1598 | // Update the dangling symlink with the digest. If it fails we can continue; it only | 1623 | // 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 | } |
| 1611 | | 1636 | |
| | 1637 | const LLDContext = struct { |
| | 1638 | data: std.ArrayList(u8), |
| | 1639 | elf: *Elf, |
| | 1640 | oom: bool = false, |
| | 1641 | }; |
| | 1642 | |
| 1612 | fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void { | 1643 | fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void { |
| 1613 | // TODO collect diagnostics and handle cleanly | 1644 | 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 | } |
| 1617 | | 1650 | |
| 1618 | fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void { | 1651 | fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void { |