| author | |
| committer | |
| log | da25ed95fce32449f70942ea77aa5e00e75dbbdd |
| tree | 6e9e979184325aa9f4d73e0c29de5e1f55f5e4f5 |
| parent | 6235cc3da4d2c6ebf7fd31242e8d82d39f5c81cf |
7 files changed, 73 insertions(+), 40 deletions(-)
src/link.zig+16-3| ... | @@ -632,15 +632,14 @@ pub const File = struct { | ... | @@ -632,15 +632,14 @@ pub const File = struct { |
| 632 | pub const UpdateDebugInfoError = Dwarf.UpdateError; | 632 | pub const UpdateDebugInfoError = Dwarf.UpdateError; |
| 633 | pub const FlushDebugInfoError = Dwarf.FlushError; | 633 | pub const FlushDebugInfoError = Dwarf.FlushError; |
| 634 | 634 | ||
| 635 | /// Note that `LinkFailure` is not a member of this error set because the error message | ||
| 636 | /// must be attached to `Zcu.failed_codegen` rather than `Compilation.link_diags`. | ||
| 635 | pub const UpdateNavError = error{ | 637 | pub const UpdateNavError = error{ |
| 636 | Overflow, | 638 | Overflow, |
| 637 | OutOfMemory, | 639 | OutOfMemory, |
| 638 | /// Indicates the error is already reported and stored in | 640 | /// Indicates the error is already reported and stored in |
| 639 | /// `failed_codegen` on the Zcu. | 641 | /// `failed_codegen` on the Zcu. |
| 640 | CodegenFail, | 642 | CodegenFail, |
| 641 | /// Indicates the error is already reported and stored in `link_diags` | ||
| 642 | /// on the Compilation. | ||
| 643 | LinkFailure, | ||
| 644 | }; | 643 | }; |
| 645 | 644 | ||
| 646 | /// Called from within CodeGen to retrieve the symbol index of a global symbol. | 645 | /// Called from within CodeGen to retrieve the symbol index of a global symbol. |
| ... | @@ -1284,6 +1283,20 @@ pub const File = struct { | ... | @@ -1284,6 +1283,20 @@ pub const File = struct { |
| 1284 | }, llvm_object, prog_node); | 1283 | }, llvm_object, prog_node); |
| 1285 | } | 1284 | } |
| 1286 | 1285 | ||
| 1286 | pub fn cgFail( | ||
| 1287 | base: *File, | ||
| 1288 | nav_index: InternPool.Nav.Index, | ||
| 1289 | comptime format: []const u8, | ||
| 1290 | args: anytype, | ||
| 1291 | ) error{ CodegenFail, OutOfMemory } { | ||
| 1292 | @branchHint(.cold); | ||
| 1293 | const zcu = base.comp.zcu.?; | ||
| 1294 | const gpa = zcu.gpa; | ||
| 1295 | try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1); | ||
| 1296 | const msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(nav_index), format, args); | ||
| 1297 | zcu.failed_codegen.putAssumeCapacityNoClobber(gpa, nav_index, msg); | ||
| 1298 | } | ||
| 1299 | |||
| 1287 | pub const C = @import("link/C.zig"); | 1300 | pub const C = @import("link/C.zig"); |
| 1288 | pub const Coff = @import("link/Coff.zig"); | 1301 | pub const Coff = @import("link/Coff.zig"); |
| 1289 | pub const Plan9 = @import("link/Plan9.zig"); | 1302 | pub const Plan9 = @import("link/Plan9.zig"); |
src/link/Dwarf.zig+2-4| ... | @@ -26,9 +26,7 @@ pub const UpdateError = error{ | ... | @@ -26,9 +26,7 @@ pub const UpdateError = error{ |
| 26 | OutOfMemory, | 26 | OutOfMemory, |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | pub const FlushError = | 29 | pub const FlushError = UpdateError || std.process.GetCwdError; |
| 30 | UpdateError || | ||
| 31 | std.process.GetCwdError; | ||
| 32 | 30 | ||
| 33 | pub const RelocError = | 31 | pub const RelocError = |
| 34 | std.fs.File.PWriteError; | 32 | std.fs.File.PWriteError; |
| ... | @@ -4312,7 +4310,7 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A | ... | @@ -4312,7 +4310,7 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A |
| 4312 | return @intFromEnum(abbrev_code); | 4310 | return @intFromEnum(abbrev_code); |
| 4313 | } | 4311 | } |
| 4314 | 4312 | ||
| 4315 | pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | 4313 | pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) !void { |
| 4316 | const zcu = pt.zcu; | 4314 | const zcu = pt.zcu; |
| 4317 | const ip = &zcu.intern_pool; | 4315 | const ip = &zcu.intern_pool; |
| 4318 | 4316 |
src/link/Elf.zig+13-2| ... | @@ -807,7 +807,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -807,7 +807,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 807 | defer tracy.end(); | 807 | defer tracy.end(); |
| 808 | 808 | ||
| 809 | const comp = self.base.comp; | 809 | const comp = self.base.comp; |
| 810 | const gpa = comp.gpa; | ||
| 811 | const diags = &comp.link_diags; | 810 | const diags = &comp.link_diags; |
| 812 | 811 | ||
| 813 | if (self.llvm_object) |llvm_object| { | 812 | if (self.llvm_object) |llvm_object| { |
| ... | @@ -821,6 +820,18 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -821,6 +820,18 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 821 | const sub_prog_node = prog_node.start("ELF Flush", 0); | 820 | const sub_prog_node = prog_node.start("ELF Flush", 0); |
| 822 | defer sub_prog_node.end(); | 821 | defer sub_prog_node.end(); |
| 823 | 822 | ||
| 823 | return flushModuleInner(self, arena, tid) catch |err| switch (err) { | ||
| 824 | error.OutOfMemory => return error.OutOfMemory, | ||
| 825 | error.LinkFailure => return error.LinkFailure, | ||
| 826 | else => |e| return diags.fail("ELF flush failed: {s}", .{@errorName(e)}), | ||
| 827 | }; | ||
| 828 | } | ||
| 829 | |||
| 830 | fn flushModuleInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | ||
| 831 | const comp = self.base.comp; | ||
| 832 | const gpa = comp.gpa; | ||
| 833 | const diags = &comp.link_diags; | ||
| 834 | |||
| 824 | const module_obj_path: ?Path = if (self.base.zcu_object_sub_path) |path| .{ | 835 | const module_obj_path: ?Path = if (self.base.zcu_object_sub_path) |path| .{ |
| 825 | .root_dir = self.base.emit.root_dir, | 836 | .root_dir = self.base.emit.root_dir, |
| 826 | .sub_path = if (fs.path.dirname(self.base.emit.sub_path)) |dirname| | 837 | .sub_path = if (fs.path.dirname(self.base.emit.sub_path)) |dirname| |
| ... | @@ -2432,7 +2443,7 @@ pub fn addCommentString(self: *Elf) !void { | ... | @@ -2432,7 +2443,7 @@ pub fn addCommentString(self: *Elf) !void { |
| 2432 | self.comment_merge_section_index = msec_index; | 2443 | self.comment_merge_section_index = msec_index; |
| 2433 | } | 2444 | } |
| 2434 | 2445 | ||
| 2435 | pub fn resolveMergeSections(self: *Elf) link.File.FlushError!void { | 2446 | pub fn resolveMergeSections(self: *Elf) !void { |
| 2436 | const tracy = trace(@src()); | 2447 | const tracy = trace(@src()); |
| 2437 | defer tracy.end(); | 2448 | defer tracy.end(); |
| 2438 | 2449 |
src/link/Elf/ZigObject.zig+12-12| ... | @@ -264,7 +264,7 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { | ... | @@ -264,7 +264,7 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 264 | } | 264 | } |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) link.File.FlushError!void { | 267 | pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void { |
| 268 | // Handle any lazy symbols that were emitted by incremental compilation. | 268 | // Handle any lazy symbols that were emitted by incremental compilation. |
| 269 | if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| { | 269 | if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| { |
| 270 | const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid); | 270 | const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid); |
| ... | @@ -279,7 +279,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) link.File. | ... | @@ -279,7 +279,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) link.File. |
| 279 | metadata.text_symbol_index, | 279 | metadata.text_symbol_index, |
| 280 | ) catch |err| return switch (err) { | 280 | ) catch |err| return switch (err) { |
| 281 | error.CodegenFail => error.LinkFailure, | 281 | error.CodegenFail => error.LinkFailure, |
| 282 | else => |e| e, | 282 | else => |e| return e, |
| 283 | }; | 283 | }; |
| 284 | if (metadata.rodata_state != .unused) self.updateLazySymbol( | 284 | if (metadata.rodata_state != .unused) self.updateLazySymbol( |
| 285 | elf_file, | 285 | elf_file, |
| ... | @@ -288,7 +288,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) link.File. | ... | @@ -288,7 +288,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) link.File. |
| 288 | metadata.rodata_symbol_index, | 288 | metadata.rodata_symbol_index, |
| 289 | ) catch |err| return switch (err) { | 289 | ) catch |err| return switch (err) { |
| 290 | error.CodegenFail => error.LinkFailure, | 290 | error.CodegenFail => error.LinkFailure, |
| 291 | else => |e| e, | 291 | else => |e| return e, |
| 292 | }; | 292 | }; |
| 293 | } | 293 | } |
| 294 | for (self.lazy_syms.values()) |*metadata| { | 294 | for (self.lazy_syms.values()) |*metadata| { |
| ... | @@ -1263,7 +1263,7 @@ fn updateNavCode( | ... | @@ -1263,7 +1263,7 @@ fn updateNavCode( |
| 1263 | shdr_index: u32, | 1263 | shdr_index: u32, |
| 1264 | code: []const u8, | 1264 | code: []const u8, |
| 1265 | stt_bits: u8, | 1265 | stt_bits: u8, |
| 1266 | ) !void { | 1266 | ) link.File.UpdateNavError!void { |
| 1267 | const zcu = pt.zcu; | 1267 | const zcu = pt.zcu; |
| 1268 | const gpa = zcu.gpa; | 1268 | const gpa = zcu.gpa; |
| 1269 | const ip = &zcu.intern_pool; | 1269 | const ip = &zcu.intern_pool; |
| ... | @@ -1342,7 +1342,7 @@ fn updateNavCode( | ... | @@ -1342,7 +1342,7 @@ fn updateNavCode( |
| 1342 | const shdr = elf_file.sections.items(.shdr)[shdr_index]; | 1342 | const shdr = elf_file.sections.items(.shdr)[shdr_index]; |
| 1343 | if (shdr.sh_type != elf.SHT_NOBITS) { | 1343 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 1344 | const file_offset = atom_ptr.offset(elf_file); | 1344 | const file_offset = atom_ptr.offset(elf_file); |
| 1345 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1345 | try elf_file.pwriteAll(code, file_offset); |
| 1346 | log.debug("writing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), file_offset, file_offset + code.len }); | 1346 | log.debug("writing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), file_offset, file_offset + code.len }); |
| 1347 | } | 1347 | } |
| 1348 | } | 1348 | } |
| ... | @@ -1355,7 +1355,7 @@ fn updateTlv( | ... | @@ -1355,7 +1355,7 @@ fn updateTlv( |
| 1355 | sym_index: Symbol.Index, | 1355 | sym_index: Symbol.Index, |
| 1356 | shndx: u32, | 1356 | shndx: u32, |
| 1357 | code: []const u8, | 1357 | code: []const u8, |
| 1358 | ) !void { | 1358 | ) link.File.UpdateNavError!void { |
| 1359 | const zcu = pt.zcu; | 1359 | const zcu = pt.zcu; |
| 1360 | const ip = &zcu.intern_pool; | 1360 | const ip = &zcu.intern_pool; |
| 1361 | const gpa = zcu.gpa; | 1361 | const gpa = zcu.gpa; |
| ... | @@ -1394,7 +1394,7 @@ fn updateTlv( | ... | @@ -1394,7 +1394,7 @@ fn updateTlv( |
| 1394 | const shdr = elf_file.sections.items(.shdr)[shndx]; | 1394 | const shdr = elf_file.sections.items(.shdr)[shndx]; |
| 1395 | if (shdr.sh_type != elf.SHT_NOBITS) { | 1395 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 1396 | const file_offset = atom_ptr.offset(elf_file); | 1396 | const file_offset = atom_ptr.offset(elf_file); |
| 1397 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1397 | try elf_file.pwriteAll(code, file_offset); |
| 1398 | log.debug("writing TLV {s} from 0x{x} to 0x{x}", .{ | 1398 | log.debug("writing TLV {s} from 0x{x} to 0x{x}", .{ |
| 1399 | atom_ptr.name(elf_file), | 1399 | atom_ptr.name(elf_file), |
| 1400 | file_offset, | 1400 | file_offset, |
| ... | @@ -1617,7 +1617,7 @@ fn updateLazySymbol( | ... | @@ -1617,7 +1617,7 @@ fn updateLazySymbol( |
| 1617 | pt: Zcu.PerThread, | 1617 | pt: Zcu.PerThread, |
| 1618 | sym: link.File.LazySymbol, | 1618 | sym: link.File.LazySymbol, |
| 1619 | symbol_index: Symbol.Index, | 1619 | symbol_index: Symbol.Index, |
| 1620 | ) link.File.FlushError!void { | 1620 | ) !void { |
| 1621 | const zcu = pt.zcu; | 1621 | const zcu = pt.zcu; |
| 1622 | const gpa = zcu.gpa; | 1622 | const gpa = zcu.gpa; |
| 1623 | 1623 | ||
| ... | @@ -1698,7 +1698,7 @@ fn updateLazySymbol( | ... | @@ -1698,7 +1698,7 @@ fn updateLazySymbol( |
| 1698 | local_sym.value = 0; | 1698 | local_sym.value = 0; |
| 1699 | local_esym.st_value = 0; | 1699 | local_esym.st_value = 0; |
| 1700 | 1700 | ||
| 1701 | try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file)); | 1701 | try elf_file.pwriteAll(code, atom_ptr.offset(elf_file)); |
| 1702 | } | 1702 | } |
| 1703 | 1703 | ||
| 1704 | const LowerConstResult = union(enum) { | 1704 | const LowerConstResult = union(enum) { |
| ... | @@ -1750,7 +1750,7 @@ fn lowerConst( | ... | @@ -1750,7 +1750,7 @@ fn lowerConst( |
| 1750 | try self.allocateAtom(atom_ptr, true, elf_file); | 1750 | try self.allocateAtom(atom_ptr, true, elf_file); |
| 1751 | errdefer self.freeNavMetadata(elf_file, sym_index); | 1751 | errdefer self.freeNavMetadata(elf_file, sym_index); |
| 1752 | 1752 | ||
| 1753 | try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file)); | 1753 | try elf_file.pwriteAll(code, atom_ptr.offset(elf_file)); |
| 1754 | 1754 | ||
| 1755 | return .{ .ok = sym_index }; | 1755 | return .{ .ok = sym_index }; |
| 1756 | } | 1756 | } |
| ... | @@ -1898,7 +1898,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 { | ... | @@ -1898,7 +1898,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 { |
| 1898 | return len; | 1898 | return len; |
| 1899 | } | 1899 | } |
| 1900 | 1900 | ||
| 1901 | fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void { | 1901 | fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) link.File.UpdateNavError!void { |
| 1902 | const atom_ptr = tr_sym.atom(elf_file).?; | 1902 | const atom_ptr = tr_sym.atom(elf_file).?; |
| 1903 | const fileoff = atom_ptr.offset(elf_file); | 1903 | const fileoff = atom_ptr.offset(elf_file); |
| 1904 | const source_addr = tr_sym.address(.{}, elf_file); | 1904 | const source_addr = tr_sym.address(.{}, elf_file); |
| ... | @@ -1908,7 +1908,7 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void { | ... | @@ -1908,7 +1908,7 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void { |
| 1908 | .x86_64 => try x86_64.writeTrampolineCode(source_addr, target_addr, &buf), | 1908 | .x86_64 => try x86_64.writeTrampolineCode(source_addr, target_addr, &buf), |
| 1909 | else => @panic("TODO implement write trampoline for this CPU arch"), | 1909 | else => @panic("TODO implement write trampoline for this CPU arch"), |
| 1910 | }; | 1910 | }; |
| 1911 | try elf_file.base.file.?.pwriteAll(out, fileoff); | 1911 | try elf_file.pwriteAll(out, fileoff); |
| 1912 | 1912 | ||
| 1913 | if (elf_file.base.child_pid) |pid| { | 1913 | if (elf_file.base.child_pid) |pid| { |
| 1914 | switch (builtin.os.tag) { | 1914 | switch (builtin.os.tag) { |
src/link/Elf/relocatable.zig+3-3| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void { | 1 | pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 2 | const gpa = comp.gpa; | 2 | const gpa = comp.gpa; |
| 3 | const diags = &comp.link_diags; | 3 | const diags = &comp.link_diags; |
| 4 | 4 | ||
| ... | @@ -130,7 +130,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!v | ... | @@ -130,7 +130,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!v |
| 130 | if (diags.hasErrors()) return error.LinkFailure; | 130 | if (diags.hasErrors()) return error.LinkFailure; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | pub fn flushObject(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void { | 133 | pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { |
| 134 | const diags = &comp.link_diags; | 134 | const diags = &comp.link_diags; |
| 135 | 135 | ||
| 136 | if (diags.hasErrors()) return error.LinkFailure; | 136 | if (diags.hasErrors()) return error.LinkFailure; |
| ... | @@ -259,7 +259,7 @@ fn initComdatGroups(elf_file: *Elf) !void { | ... | @@ -259,7 +259,7 @@ fn initComdatGroups(elf_file: *Elf) !void { |
| 259 | } | 259 | } |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | fn updateSectionSizes(elf_file: *Elf) link.File.FlushError!void { | 262 | fn updateSectionSizes(elf_file: *Elf) !void { |
| 263 | const slice = elf_file.sections.slice(); | 263 | const slice = elf_file.sections.slice(); |
| 264 | for (slice.items(.atom_list_2)) |*atom_list| { | 264 | for (slice.items(.atom_list_2)) |*atom_list| { |
| 265 | if (atom_list.atoms.keys().len == 0) continue; | 265 | if (atom_list.atoms.keys().len == 0) continue; |
src/link/MachO.zig+4-4| ... | @@ -3423,7 +3423,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { | ... | @@ -3423,7 +3423,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3423 | }; | 3423 | }; |
| 3424 | } | 3424 | } |
| 3425 | 3425 | ||
| 3426 | pub fn growSection(self: *MachO, sect_index: u8, needed_size: u64) error{ OutOfMemory, LinkFailure }!void { | 3426 | pub fn growSection(self: *MachO, sect_index: u8, needed_size: u64) !void { |
| 3427 | if (self.base.isRelocatable()) { | 3427 | if (self.base.isRelocatable()) { |
| 3428 | try self.growSectionRelocatable(sect_index, needed_size); | 3428 | try self.growSectionRelocatable(sect_index, needed_size); |
| 3429 | } else { | 3429 | } else { |
| ... | @@ -3431,7 +3431,7 @@ pub fn growSection(self: *MachO, sect_index: u8, needed_size: u64) error{ OutOfM | ... | @@ -3431,7 +3431,7 @@ pub fn growSection(self: *MachO, sect_index: u8, needed_size: u64) error{ OutOfM |
| 3431 | } | 3431 | } |
| 3432 | } | 3432 | } |
| 3433 | 3433 | ||
| 3434 | fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) error{ OutOfMemory, LinkFailure }!void { | 3434 | fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !void { |
| 3435 | const diags = &self.base.comp.link_diags; | 3435 | const diags = &self.base.comp.link_diags; |
| 3436 | const sect = &self.sections.items(.header)[sect_index]; | 3436 | const sect = &self.sections.items(.header)[sect_index]; |
| 3437 | 3437 | ||
| ... | @@ -3480,7 +3480,7 @@ fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) err | ... | @@ -3480,7 +3480,7 @@ fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) err |
| 3480 | seg.vmsize = needed_size; | 3480 | seg.vmsize = needed_size; |
| 3481 | } | 3481 | } |
| 3482 | 3482 | ||
| 3483 | fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) error{ OutOfMemory, LinkFailure }!void { | 3483 | fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !void { |
| 3484 | const sect = &self.sections.items(.header)[sect_index]; | 3484 | const sect = &self.sections.items(.header)[sect_index]; |
| 3485 | 3485 | ||
| 3486 | if (!sect.isZerofill()) { | 3486 | if (!sect.isZerofill()) { |
| ... | @@ -3490,7 +3490,7 @@ fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) error{ | ... | @@ -3490,7 +3490,7 @@ fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) error{ |
| 3490 | sect.size = 0; | 3490 | sect.size = 0; |
| 3491 | 3491 | ||
| 3492 | // Must move the entire section. | 3492 | // Must move the entire section. |
| 3493 | const alignment = try self.alignPow(sect.@"align"); | 3493 | const alignment = try math.powi(u32, 2, sect.@"align"); |
| 3494 | const new_offset = try self.findFreeSpace(needed_size, alignment); | 3494 | const new_offset = try self.findFreeSpace(needed_size, alignment); |
| 3495 | const new_addr = self.findFreeSpaceVirtual(needed_size, alignment); | 3495 | const new_addr = self.findFreeSpaceVirtual(needed_size, alignment); |
| 3496 | 3496 |
src/link/MachO/ZigObject.zig+23-12| ... | @@ -559,18 +559,26 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) | ... | @@ -559,18 +559,26 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) |
| 559 | 559 | ||
| 560 | // Most lazy symbols can be updated on first use, but | 560 | // Most lazy symbols can be updated on first use, but |
| 561 | // anyerror needs to wait for everything to be flushed. | 561 | // anyerror needs to wait for everything to be flushed. |
| 562 | if (metadata.text_state != .unused) try self.updateLazySymbol( | 562 | if (metadata.text_state != .unused) self.updateLazySymbol( |
| 563 | macho_file, | 563 | macho_file, |
| 564 | pt, | 564 | pt, |
| 565 | .{ .kind = .code, .ty = .anyerror_type }, | 565 | .{ .kind = .code, .ty = .anyerror_type }, |
| 566 | metadata.text_symbol_index, | 566 | metadata.text_symbol_index, |
| 567 | ); | 567 | ) catch |err| switch (err) { |
| 568 | if (metadata.const_state != .unused) try self.updateLazySymbol( | 568 | error.OutOfMemory => return error.OutOfMemory, |
| 569 | error.LinkFailure => return error.LinkFailure, | ||
| 570 | else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}), | ||
| 571 | }; | ||
| 572 | if (metadata.const_state != .unused) self.updateLazySymbol( | ||
| 569 | macho_file, | 573 | macho_file, |
| 570 | pt, | 574 | pt, |
| 571 | .{ .kind = .const_data, .ty = .anyerror_type }, | 575 | .{ .kind = .const_data, .ty = .anyerror_type }, |
| 572 | metadata.const_symbol_index, | 576 | metadata.const_symbol_index, |
| 573 | ); | 577 | ) catch |err| switch (err) { |
| 578 | error.OutOfMemory => return error.OutOfMemory, | ||
| 579 | error.LinkFailure => return error.LinkFailure, | ||
| 580 | else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}), | ||
| 581 | }; | ||
| 574 | } | 582 | } |
| 575 | for (self.lazy_syms.values()) |*metadata| { | 583 | for (self.lazy_syms.values()) |*metadata| { |
| 576 | if (metadata.text_state != .unused) metadata.text_state = .flushed; | 584 | if (metadata.text_state != .unused) metadata.text_state = .flushed; |
| ... | @@ -803,7 +811,7 @@ pub fn updateFunc( | ... | @@ -803,7 +811,7 @@ pub fn updateFunc( |
| 803 | .ok => code_buffer.items, | 811 | .ok => code_buffer.items, |
| 804 | .fail => |em| { | 812 | .fail => |em| { |
| 805 | try zcu.failed_codegen.put(gpa, func.owner_nav, em); | 813 | try zcu.failed_codegen.put(gpa, func.owner_nav, em); |
| 806 | return; | 814 | return error.CodegenFail; |
| 807 | }, | 815 | }, |
| 808 | }; | 816 | }; |
| 809 | 817 | ||
| ... | @@ -855,7 +863,8 @@ pub fn updateFunc( | ... | @@ -855,7 +863,8 @@ pub fn updateFunc( |
| 855 | } | 863 | } |
| 856 | const target_sym = self.symbols.items[sym_index]; | 864 | const target_sym = self.symbols.items[sym_index]; |
| 857 | const source_sym = self.symbols.items[target_sym.getExtra(macho_file).trampoline]; | 865 | const source_sym = self.symbols.items[target_sym.getExtra(macho_file).trampoline]; |
| 858 | try writeTrampoline(source_sym, target_sym, macho_file); | 866 | writeTrampoline(source_sym, target_sym, macho_file) catch |err| |
| 867 | return macho_file.base.cgFail(func.owner_nav, "failed to write trampoline: {s}", .{@errorName(err)}); | ||
| 859 | } | 868 | } |
| 860 | } | 869 | } |
| 861 | 870 | ||
| ... | @@ -955,7 +964,6 @@ fn updateNavCode( | ... | @@ -955,7 +964,6 @@ fn updateNavCode( |
| 955 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 964 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
| 956 | }; | 965 | }; |
| 957 | 966 | ||
| 958 | const diags = &macho_file.base.comp.link_diags; | ||
| 959 | const sect = &macho_file.sections.items(.header)[sect_index]; | 967 | const sect = &macho_file.sections.items(.header)[sect_index]; |
| 960 | const sym = &self.symbols.items[sym_index]; | 968 | const sym = &self.symbols.items[sym_index]; |
| 961 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; | 969 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| ... | @@ -984,7 +992,8 @@ fn updateNavCode( | ... | @@ -984,7 +992,8 @@ fn updateNavCode( |
| 984 | const need_realloc = code.len > capacity or !required_alignment.check(atom.value); | 992 | const need_realloc = code.len > capacity or !required_alignment.check(atom.value); |
| 985 | 993 | ||
| 986 | if (need_realloc) { | 994 | if (need_realloc) { |
| 987 | atom.grow(macho_file) catch |err| return diags.fail("failed to grow atom: {s}", .{@errorName(err)}); | 995 | atom.grow(macho_file) catch |err| |
| 996 | return macho_file.base.cgFail(nav_index, "failed to grow atom: {s}", .{@errorName(err)}); | ||
| 988 | log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom.value }); | 997 | log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom.value }); |
| 989 | if (old_vaddr != atom.value) { | 998 | if (old_vaddr != atom.value) { |
| 990 | sym.value = 0; | 999 | sym.value = 0; |
| ... | @@ -997,7 +1006,8 @@ fn updateNavCode( | ... | @@ -997,7 +1006,8 @@ fn updateNavCode( |
| 997 | sect.size = needed_size; | 1006 | sect.size = needed_size; |
| 998 | } | 1007 | } |
| 999 | } else { | 1008 | } else { |
| 1000 | try atom.allocate(macho_file); | 1009 | atom.allocate(macho_file) catch |err| |
| 1010 | return macho_file.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(err)}); | ||
| 1001 | errdefer self.freeNavMetadata(macho_file, sym_index); | 1011 | errdefer self.freeNavMetadata(macho_file, sym_index); |
| 1002 | 1012 | ||
| 1003 | sym.value = 0; | 1013 | sym.value = 0; |
| ... | @@ -1006,7 +1016,8 @@ fn updateNavCode( | ... | @@ -1006,7 +1016,8 @@ fn updateNavCode( |
| 1006 | 1016 | ||
| 1007 | if (!sect.isZerofill()) { | 1017 | if (!sect.isZerofill()) { |
| 1008 | const file_offset = sect.offset + atom.value; | 1018 | const file_offset = sect.offset + atom.value; |
| 1009 | try macho_file.pwriteAll(code, file_offset); | 1019 | macho_file.base.file.?.pwriteAll(code, file_offset) catch |err| |
| 1020 | return macho_file.base.cgFail(nav_index, "failed to write output file: {s}", .{@errorName(err)}); | ||
| 1010 | } | 1021 | } |
| 1011 | } | 1022 | } |
| 1012 | 1023 | ||
| ... | @@ -1353,7 +1364,7 @@ fn updateLazySymbol( | ... | @@ -1353,7 +1364,7 @@ fn updateLazySymbol( |
| 1353 | pt: Zcu.PerThread, | 1364 | pt: Zcu.PerThread, |
| 1354 | lazy_sym: link.File.LazySymbol, | 1365 | lazy_sym: link.File.LazySymbol, |
| 1355 | symbol_index: Symbol.Index, | 1366 | symbol_index: Symbol.Index, |
| 1356 | ) error{ OutOfMemory, LinkFailure }!void { | 1367 | ) !void { |
| 1357 | const zcu = pt.zcu; | 1368 | const zcu = pt.zcu; |
| 1358 | const gpa = zcu.gpa; | 1369 | const gpa = zcu.gpa; |
| 1359 | const diags = &macho_file.base.comp.link_diags; | 1370 | const diags = &macho_file.base.comp.link_diags; |
| ... | @@ -1494,7 +1505,7 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, macho_file: *MachO) !void { | ... | @@ -1494,7 +1505,7 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, macho_file: *MachO) !void { |
| 1494 | .x86_64 => try x86_64.writeTrampolineCode(source_addr, target_addr, &buf), | 1505 | .x86_64 => try x86_64.writeTrampolineCode(source_addr, target_addr, &buf), |
| 1495 | else => @panic("TODO implement write trampoline for this CPU arch"), | 1506 | else => @panic("TODO implement write trampoline for this CPU arch"), |
| 1496 | }; | 1507 | }; |
| 1497 | try macho_file.pwriteAll(out, fileoff); | 1508 | try macho_file.base.file.?.pwriteAll(out, fileoff); |
| 1498 | } | 1509 | } |
| 1499 | 1510 | ||
| 1500 | pub fn getOrCreateMetadataForNav( | 1511 | pub fn getOrCreateMetadataForNav( |