| ... | ... | @@ -1591,9 +1591,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1591 | 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 | 1604 | const llvm = @import("../llvm.zig"); |
| 1595 | | const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0); |
| 1596 | | if (!ok) return error.LLDReportedFailure; |
| 1605 | const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, |
| 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 | 1623 | // Update the dangling symlink with the digest. If it fails we can continue; it only |
| 1599 | 1624 | // means that the next invocation will have an unnecessary cache miss. |
| ... | ... | @@ -1609,10 +1634,18 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1609 | 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 | 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 | 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 | 1651 | fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void { |