From de0f7fcf526312088e4b373c6ed7436427080087 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Oct 2024 23:32:10 -0700 Subject: [PATCH] unify parsing codepaths between relocatable and non --- src/link/Elf.zig | 25 ++++++++++++++-------- src/link/Elf/Object.zig | 16 ++------------- src/link/Elf/relocatable.zig | 40 ++---------------------------------- 3 files changed, 21 insertions(+), 60 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index f0dba06e41..261f4c6430 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -765,6 +765,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { const target = self.getTarget(); const debug_fmt_strip = comp.config.debug_format == .strip; const default_sym_version = self.default_sym_version; + const is_static_lib = self.base.isStaticLib(); if (comp.verbose_link) { const argv = &self.dump_argv_list; @@ -780,7 +781,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { .res => unreachable, .dso_exact => @panic("TODO"), .object => |obj| try parseObject(self, obj), - .archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, &self.first_eflags, target, debug_fmt_strip, default_sym_version, &self.objects, obj), + .archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, &self.first_eflags, target, debug_fmt_strip, default_sym_version, &self.objects, obj, is_static_lib), .dso => |dso| try parseDso(gpa, diags, dso, &self.shared_objects, &self.files, target), } } @@ -823,17 +824,17 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid); + if (module_obj_path) |path| openParseObjectReportingFailure(self, path); + switch (comp.config.output_mode) { - .Obj => return relocatable.flushObject(self, comp, module_obj_path), + .Obj => return relocatable.flushObject(self, comp), .Lib => switch (comp.config.link_mode) { .dynamic => {}, - .static => return relocatable.flushStaticLib(self, comp, module_obj_path), + .static => return relocatable.flushStaticLib(self, comp), }, .Exe => {}, } - if (module_obj_path) |path| openParseObjectReportingFailure(self, path); - if (diags.hasErrors()) return error.FlushFailure; // If we haven't already, create a linker-generated input file comprising of @@ -1149,7 +1150,10 @@ fn parseObject(self: *Elf, obj: link.Input.Object) ParseError!void { try self.objects.append(gpa, index); const object = self.file(index).?.object; - try object.parse(gpa, diags, obj.path, handle, first_eflags, target, debug_fmt_strip, default_sym_version); + try object.parseCommon(gpa, diags, obj.path, handle, target, first_eflags); + if (!self.base.isStaticLib()) { + try object.parse(gpa, diags, obj.path, handle, target, debug_fmt_strip, default_sym_version); + } } fn parseArchive( @@ -1163,6 +1167,7 @@ fn parseArchive( default_sym_version: elf.Versym, objects: *std.ArrayListUnmanaged(File.Index), obj: link.Input.Object, + is_static_lib: bool, ) ParseError!void { const tracy = trace(@src()); defer tracy.end(); @@ -1171,13 +1176,17 @@ fn parseArchive( var archive = try Archive.parse(gpa, diags, file_handles, obj.path, fh); defer archive.deinit(gpa); + const init_alive = if (is_static_lib) true else obj.must_link; + for (archive.objects) |extracted| { const index: File.Index = @intCast(try files.addOne(gpa)); files.set(index, .{ .object = extracted }); const object = &files.items(.data)[index].object; object.index = index; - object.alive = obj.must_link; - try object.parse(gpa, diags, obj.path, obj.file, first_eflags, target, debug_fmt_strip, default_sym_version); + object.alive = init_alive; + try object.parseCommon(gpa, diags, obj.path, obj.file, target, first_eflags); + if (!is_static_lib) + try object.parse(gpa, diags, obj.path, obj.file, target, debug_fmt_strip, default_sym_version); try objects.append(gpa, index); } } diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index d8ba812019..d1ff168341 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -69,13 +69,10 @@ pub fn parse( /// For error reporting purposes only. path: Path, handle: fs.File, - first_eflags: *?elf.Word, target: std.Target, debug_fmt_strip: bool, default_sym_version: elf.Versym, ) !void { - try self.parseCommon(gpa, diags, path, handle, first_eflags, target); - // Append null input merge section try self.input_merge_sections.append(gpa, .{}); // Allocate atom index 0 to null atom @@ -95,14 +92,14 @@ pub fn parse( } } -fn parseCommon( +pub fn parseCommon( self: *Object, gpa: Allocator, diags: *Diags, path: Path, handle: fs.File, - first_eflags: *?elf.Word, target: std.Target, + first_eflags: *?elf.Word, ) !void { const offset = if (self.archive) |ar| ar.offset else 0; const file_size = (try handle.stat()).size; @@ -1036,15 +1033,6 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { } } -pub fn parseAr(self: *Object, path: Path, elf_file: *Elf) !void { - const gpa = elf_file.base.comp.gpa; - const diags = &elf_file.base.comp.link_diags; - const handle = elf_file.fileHandle(self.file_handle); - const first_eflags = &elf_file.first_eflags; - const target = elf_file.base.comp.root_mod.resolved_target.result; - try self.parseCommon(gpa, diags, path, handle, first_eflags, target); -} - pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void { const comp = elf_file.base.comp; const gpa = comp.gpa; diff --git a/src/link/Elf/relocatable.zig b/src/link/Elf/relocatable.zig index 46622fdf69..f9c02cb5d0 100644 --- a/src/link/Elf/relocatable.zig +++ b/src/link/Elf/relocatable.zig @@ -1,11 +1,7 @@ -pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { +pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void { const gpa = comp.gpa; const diags = &comp.link_diags; - if (module_obj_path) |path| { - parseObjectStaticLibReportingFailure(elf_file, path); - } - if (diags.hasErrors()) return error.FlushFailure; // First, we flush relocatable object file generated with our backends. @@ -134,11 +130,9 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path if (diags.hasErrors()) return error.FlushFailure; } -pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { +pub fn flushObject(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void { const diags = &comp.link_diags; - if (module_obj_path) |path| elf_file.openParseObjectReportingFailure(path); - if (diags.hasErrors()) return error.FlushFailure; // Now, we are ready to resolve the symbols across all input files. @@ -188,36 +182,6 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) l if (diags.hasErrors()) return error.FlushFailure; } -fn parseObjectStaticLibReportingFailure(elf_file: *Elf, path: Path) void { - const diags = &elf_file.base.comp.link_diags; - parseObjectStaticLib(elf_file, path) catch |err| switch (err) { - error.LinkFailure => return, - else => |e| diags.addParseError(path, "parsing object failed: {s}", .{@errorName(e)}), - }; -} - -fn parseObjectStaticLib(elf_file: *Elf, path: Path) Elf.ParseError!void { - const gpa = elf_file.base.comp.gpa; - const file_handles = &elf_file.file_handles; - - const handle = try path.root_dir.handle.openFile(path.sub_path, .{}); - const fh = try Elf.addFileHandle(gpa, file_handles, handle); - - const index: File.Index = @intCast(try elf_file.files.addOne(gpa)); - elf_file.files.set(index, .{ .object = .{ - .path = .{ - .root_dir = path.root_dir, - .sub_path = try gpa.dupe(u8, path.sub_path), - }, - .file_handle = fh, - .index = index, - } }); - try elf_file.objects.append(gpa, index); - - const object = elf_file.file(index).?.object; - try object.parseAr(path, elf_file); -} - fn claimUnresolved(elf_file: *Elf) void { if (elf_file.zigObjectPtr()) |zig_object| { zig_object.claimUnresolvedRelocatable(elf_file);