authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-27 15:07:05+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-27 15:07:05+02:00
log09863fc97043f3aadcad476c3eda8f3e3dde18dd
tree9c991287ed9fb02d66e3450d6cefb047fc426c37
parente178580d864407864ebb4d95bb28b041b7b0870a

elf: emit fatal linker error if we run out of VM space with self-hosted backends


1 files changed, 51 insertions(+), 0 deletions(-)

src/link/Elf.zig+51
...@@ -857,6 +857,17 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {...@@ -857,6 +857,17 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
857 // TODO mark relocs dirty857 // TODO mark relocs dirty
858 }858 }
859 try self.growSegment(shdr_index, needed_size);859 try self.growSegment(shdr_index, needed_size);
860
861 if (self.zig_module_index != null) {
862 // TODO self-hosted backends cannot yet handle this condition correctly as the linker
863 // cannot update emitted virtual addresses of symbols already committed to the final file.
864 var err = try self.addErrorWithNotes(2);
865 try err.addMsg(self, "fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{
866 phdr_index,
867 });
868 try err.addNote(self, "TODO: emit relocations to memory locations in self-hosted backends", .{});
869 try err.addNote(self, "as a workaround, try increasing pre-allocated virtual memory of each segment", .{});
870 }
860 }871 }
861872
862 shdr.sh_size = needed_size;873 shdr.sh_size = needed_size;
...@@ -3972,6 +3983,46 @@ pub fn comdatGroupOwner(self: *Elf, index: ComdatGroupOwner.Index) *ComdatGroupO...@@ -3972,6 +3983,46 @@ pub fn comdatGroupOwner(self: *Elf, index: ComdatGroupOwner.Index) *ComdatGroupO
3972 return &self.comdat_groups_owners.items[index];3983 return &self.comdat_groups_owners.items[index];
3973}3984}
39743985
3986const ErrorWithNotes = struct {
3987 /// Allocated index in misc_errors array.
3988 index: usize,
3989
3990 /// Next available note slot.
3991 note_slot: usize = 0,
3992
3993 pub fn addMsg(
3994 err: ErrorWithNotes,
3995 elf_file: *Elf,
3996 comptime format: []const u8,
3997 args: anytype,
3998 ) error{OutOfMemory}!void {
3999 const gpa = elf_file.base.allocator;
4000 const err_msg = &elf_file.misc_errors.items[err.index];
4001 err_msg.msg = try std.fmt.allocPrint(gpa, format, args);
4002 }
4003
4004 pub fn addNote(
4005 err: *ErrorWithNotes,
4006 elf_file: *Elf,
4007 comptime format: []const u8,
4008 args: anytype,
4009 ) error{OutOfMemory}!void {
4010 const gpa = elf_file.base.allocator;
4011 const err_msg = &elf_file.misc_errors.items[err.index];
4012 assert(err.note_slot < err_msg.notes.len);
4013 err_msg.notes[err.note_slot] = .{ .msg = try std.fmt.allocPrint(gpa, format, args) };
4014 err.note_slot += 1;
4015 }
4016};
4017
4018fn addErrorWithNotes(self: *Elf, note_count: usize) error{OutOfMemory}!ErrorWithNotes {
4019 const gpa = self.base.allocator;
4020 const index = self.misc_errors.items.len;
4021 const err = try self.misc_errors.addOne(gpa);
4022 err.* = .{ .msg = undefined, .notes = try gpa.alloc(link.File.ErrorMsg, note_count) };
4023 return .{ .index = index };
4024}
4025
3975fn reportUndefined(self: *Elf, undefs: anytype) !void {4026fn reportUndefined(self: *Elf, undefs: anytype) !void {
3976 const gpa = self.base.allocator;4027 const gpa = self.base.allocator;
3977 const max_notes = 4;4028 const max_notes = 4;