Commit de0f7fcf52

Andrew Kelley <andrew@ziglang.org>
2024-10-19 08:32:10
unify parsing codepaths between relocatable and non
1 parent 12f3a7c
Changed files (3)
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;
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);
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);
     }
 }