link: fixed bugs uncovered by changing the cache mode

This commit is contained in:
Jacob Young 2025-03-02 16:37:29 -05:00
parent 725c825829
commit d741be512b
3 changed files with 35 additions and 45 deletions

View file

@ -3279,13 +3279,13 @@ const InitMetadataOptions = struct {
pub fn closeDebugInfo(self: *MachO) bool {
const d_sym = &(self.d_sym orelse return false);
d_sym.deinit();
self.d_sym = null;
d_sym.file.?.close();
d_sym.file = null;
return true;
}
pub fn reopenDebugInfo(self: *MachO) !void {
assert(self.d_sym == null);
assert(self.d_sym.?.file == null);
assert(!self.base.comp.config.use_llvm);
assert(self.base.comp.config.debug_format == .dwarf);
@ -3302,13 +3302,10 @@ pub fn reopenDebugInfo(self: *MachO) !void {
var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(d_sym_path, .{});
defer d_sym_bundle.close();
const d_sym_file = try d_sym_bundle.createFile(self.base.emit.sub_path, .{
self.d_sym.?.file = try d_sym_bundle.createFile(fs.path.basename(self.base.emit.sub_path), .{
.truncate = false,
.read = true,
});
self.d_sym = .{ .allocator = gpa, .file = d_sym_file };
try self.d_sym.?.initMetadata(self);
}
// TODO: move to ZigObject
@ -3367,7 +3364,9 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {
if (options.zo.dwarf) |*dwarf| {
// Create dSYM bundle.
log.debug("creating {s}.dSYM bundle", .{options.emit.sub_path});
self.d_sym = .{ .allocator = self.base.comp.gpa, .file = null };
try self.reopenDebugInfo();
try self.d_sym.?.initMetadata(self);
try dwarf.initMetadata();
}
}

View file

@ -1,5 +1,5 @@
allocator: Allocator,
file: fs.File,
file: ?fs.File,
symtab_cmd: macho.symtab_command = .{},
uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 },
@ -118,9 +118,9 @@ pub fn growSection(
});
if (requires_file_copy) {
const amt = try self.file.copyRangeAll(
const amt = try self.file.?.copyRangeAll(
sect.offset,
self.file,
self.file.?,
new_offset,
existing_size,
);
@ -129,7 +129,7 @@ pub fn growSection(
sect.offset = @intCast(new_offset);
} else if (sect.offset + allocated_size == std.math.maxInt(u64)) {
try self.file.setEndPos(sect.offset + needed_size);
try self.file.?.setEndPos(sect.offset + needed_size);
}
sect.size = needed_size;
@ -165,7 +165,7 @@ fn detectAllocCollision(self: *DebugSymbols, start: u64, size: u64) !?u64 {
}
}
if (at_end) try self.file.setEndPos(end);
if (at_end) try self.file.?.setEndPos(end);
return null;
}
@ -195,7 +195,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
sym_name,
file_offset,
});
try self.file.pwriteAll(mem.asBytes(&addr), file_offset);
try self.file.?.pwriteAll(mem.asBytes(&addr), file_offset);
}
self.finalizeDwarfSegment(macho_file);
@ -208,7 +208,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
pub fn deinit(self: *DebugSymbols) void {
const gpa = self.allocator;
self.file.close();
if (self.file) |file| file.close();
self.segments.deinit(gpa);
self.sections.deinit(gpa);
self.relocs.deinit(gpa);
@ -320,7 +320,7 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u
assert(stream.pos == needed_size);
try self.file.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
try self.file.?.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
return .{ ncmds, buffer.len };
}
@ -346,7 +346,7 @@ fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: usize, sizeofcmds
log.debug("writing Mach-O header {}", .{header});
try self.file.pwriteAll(mem.asBytes(&header), 0);
try self.file.?.pwriteAll(mem.asBytes(&header), 0);
}
fn allocatedSize(self: *DebugSymbols, start: u64) u64 {
@ -404,7 +404,7 @@ pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 {
internal.writeSymtab(macho_file, self);
}
try self.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
try self.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
return off + cmd.nsyms * @sizeOf(macho.nlist_64);
}
@ -412,7 +412,7 @@ pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 {
pub fn writeStrtab(self: *DebugSymbols, off: u32) !u32 {
const cmd = &self.symtab_cmd;
cmd.stroff = off;
try self.file.pwriteAll(self.strtab.items, cmd.stroff);
try self.file.?.pwriteAll(self.strtab.items, cmd.stroff);
return off + cmd.strsize;
}

View file

@ -61,6 +61,18 @@ pub fn createEmpty(
const gpa = comp.gpa;
const target = comp.root_mod.resolved_target.result;
assert(!comp.config.use_lld); // Caught by Compilation.Config.resolve
assert(!comp.config.use_llvm); // Caught by Compilation.Config.resolve
assert(target.ofmt == .spirv); // Caught by Compilation.Config.resolve
switch (target.cpu.arch) {
.spirv, .spirv32, .spirv64 => {},
else => unreachable, // Caught by Compilation.Config.resolve.
}
switch (target.os.tag) {
.opencl, .opengl, .vulkan => {},
else => unreachable, // Caught by Compilation.Config.resolve.
}
const self = try arena.create(SpirV);
self.* = .{
.base = .{
@ -79,15 +91,11 @@ pub fn createEmpty(
};
errdefer self.deinit();
switch (target.cpu.arch) {
.spirv, .spirv32, .spirv64 => {},
else => unreachable, // Caught by Compilation.Config.resolve.
}
switch (target.os.tag) {
.opencl, .opengl, .vulkan => {},
else => unreachable, // Caught by Compilation.Config.resolve.
}
// TODO: read the file and keep valid parts instead of truncating
self.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{
.truncate = true,
.read = true,
});
return self;
}
@ -98,24 +106,7 @@ pub fn open(
emit: Path,
options: link.File.OpenOptions,
) !*SpirV {
const target = comp.root_mod.resolved_target.result;
const use_lld = build_options.have_llvm and comp.config.use_lld;
const use_llvm = comp.config.use_llvm;
assert(!use_llvm); // Caught by Compilation.Config.resolve.
assert(!use_lld); // Caught by Compilation.Config.resolve.
assert(target.ofmt == .spirv); // Caught by Compilation.Config.resolve.
const spirv = try createEmpty(arena, comp, emit, options);
errdefer spirv.base.destroy();
// TODO: read the file and keep valid parts instead of truncating
const file = try emit.root_dir.handle.createFile(emit.sub_path, .{
.truncate = true,
.read = true,
});
spirv.base.file = file;
return spirv;
return createEmpty(arena, comp, emit, options);
}
pub fn deinit(self: *SpirV) void {