authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-18 23:32:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 16:27:38-07:00
logde0f7fcf526312088e4b373c6ed7436427080087
tree9793bf83f7c1eaf893754af273b8fbd6ea772796
parent12f3a7c3c202475c67b639c369829a0390cfb0f8

unify parsing codepaths between relocatable and non


3 files changed, 21 insertions(+), 60 deletions(-)

src/link/Elf.zig+17-8
......@@ -765,6 +765,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
765765 const target = self.getTarget();
766766 const debug_fmt_strip = comp.config.debug_format == .strip;
767767 const default_sym_version = self.default_sym_version;
768 const is_static_lib = self.base.isStaticLib();
768769
769770 if (comp.verbose_link) {
770771 const argv = &self.dump_argv_list;
......@@ -780,7 +781,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
780781 .res => unreachable,
781782 .dso_exact => @panic("TODO"),
782783 .object => |obj| try parseObject(self, obj),
783 .archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, &self.first_eflags, target, debug_fmt_strip, default_sym_version, &self.objects, obj),
784 .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),
784785 .dso => |dso| try parseDso(gpa, diags, dso, &self.shared_objects, &self.files, target),
785786 }
786787}
......@@ -823,17 +824,17 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
823824
824825 if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid);
825826
827 if (module_obj_path) |path| openParseObjectReportingFailure(self, path);
828
826829 switch (comp.config.output_mode) {
827 .Obj => return relocatable.flushObject(self, comp, module_obj_path),
830 .Obj => return relocatable.flushObject(self, comp),
828831 .Lib => switch (comp.config.link_mode) {
829832 .dynamic => {},
830 .static => return relocatable.flushStaticLib(self, comp, module_obj_path),
833 .static => return relocatable.flushStaticLib(self, comp),
831834 },
832835 .Exe => {},
833836 }
834837
835 if (module_obj_path) |path| openParseObjectReportingFailure(self, path);
836
837838 if (diags.hasErrors()) return error.FlushFailure;
838839
839840 // 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 {
11491150 try self.objects.append(gpa, index);
11501151
11511152 const object = self.file(index).?.object;
1152 try object.parse(gpa, diags, obj.path, handle, first_eflags, target, debug_fmt_strip, default_sym_version);
1153 try object.parseCommon(gpa, diags, obj.path, handle, target, first_eflags);
1154 if (!self.base.isStaticLib()) {
1155 try object.parse(gpa, diags, obj.path, handle, target, debug_fmt_strip, default_sym_version);
1156 }
11531157}
11541158
11551159fn parseArchive(
......@@ -1163,6 +1167,7 @@ fn parseArchive(
11631167 default_sym_version: elf.Versym,
11641168 objects: *std.ArrayListUnmanaged(File.Index),
11651169 obj: link.Input.Object,
1170 is_static_lib: bool,
11661171) ParseError!void {
11671172 const tracy = trace(@src());
11681173 defer tracy.end();
......@@ -1171,13 +1176,17 @@ fn parseArchive(
11711176 var archive = try Archive.parse(gpa, diags, file_handles, obj.path, fh);
11721177 defer archive.deinit(gpa);
11731178
1179 const init_alive = if (is_static_lib) true else obj.must_link;
1180
11741181 for (archive.objects) |extracted| {
11751182 const index: File.Index = @intCast(try files.addOne(gpa));
11761183 files.set(index, .{ .object = extracted });
11771184 const object = &files.items(.data)[index].object;
11781185 object.index = index;
1179 object.alive = obj.must_link;
1180 try object.parse(gpa, diags, obj.path, obj.file, first_eflags, target, debug_fmt_strip, default_sym_version);
1186 object.alive = init_alive;
1187 try object.parseCommon(gpa, diags, obj.path, obj.file, target, first_eflags);
1188 if (!is_static_lib)
1189 try object.parse(gpa, diags, obj.path, obj.file, target, debug_fmt_strip, default_sym_version);
11811190 try objects.append(gpa, index);
11821191 }
11831192}
src/link/Elf/Object.zig+2-14
......@@ -69,13 +69,10 @@ pub fn parse(
6969 /// For error reporting purposes only.
7070 path: Path,
7171 handle: fs.File,
72 first_eflags: *?elf.Word,
7372 target: std.Target,
7473 debug_fmt_strip: bool,
7574 default_sym_version: elf.Versym,
7675) !void {
77 try self.parseCommon(gpa, diags, path, handle, first_eflags, target);
78
7976 // Append null input merge section
8077 try self.input_merge_sections.append(gpa, .{});
8178 // Allocate atom index 0 to null atom
......@@ -95,14 +92,14 @@ pub fn parse(
9592 }
9693}
9794
98fn parseCommon(
95pub fn parseCommon(
9996 self: *Object,
10097 gpa: Allocator,
10198 diags: *Diags,
10299 path: Path,
103100 handle: fs.File,
104 first_eflags: *?elf.Word,
105101 target: std.Target,
102 first_eflags: *?elf.Word,
106103) !void {
107104 const offset = if (self.archive) |ar| ar.offset else 0;
108105 const file_size = (try handle.stat()).size;
......@@ -1036,15 +1033,6 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
10361033 }
10371034}
10381035
1039pub fn parseAr(self: *Object, path: Path, elf_file: *Elf) !void {
1040 const gpa = elf_file.base.comp.gpa;
1041 const diags = &elf_file.base.comp.link_diags;
1042 const handle = elf_file.fileHandle(self.file_handle);
1043 const first_eflags = &elf_file.first_eflags;
1044 const target = elf_file.base.comp.root_mod.resolved_target.result;
1045 try self.parseCommon(gpa, diags, path, handle, first_eflags, target);
1046}
1047
10481036pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {
10491037 const comp = elf_file.base.comp;
10501038 const gpa = comp.gpa;
src/link/Elf/relocatable.zig+2-38
......@@ -1,11 +1,7 @@
1pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void {
1pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void {
22 const gpa = comp.gpa;
33 const diags = &comp.link_diags;
44
5 if (module_obj_path) |path| {
6 parseObjectStaticLibReportingFailure(elf_file, path);
7 }
8
95 if (diags.hasErrors()) return error.FlushFailure;
106
117 // 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
134130 if (diags.hasErrors()) return error.FlushFailure;
135131}
136132
137pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void {
133pub fn flushObject(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void {
138134 const diags = &comp.link_diags;
139135
140 if (module_obj_path) |path| elf_file.openParseObjectReportingFailure(path);
141
142136 if (diags.hasErrors()) return error.FlushFailure;
143137
144138 // 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
188182 if (diags.hasErrors()) return error.FlushFailure;
189183}
190184
191fn parseObjectStaticLibReportingFailure(elf_file: *Elf, path: Path) void {
192 const diags = &elf_file.base.comp.link_diags;
193 parseObjectStaticLib(elf_file, path) catch |err| switch (err) {
194 error.LinkFailure => return,
195 else => |e| diags.addParseError(path, "parsing object failed: {s}", .{@errorName(e)}),
196 };
197}
198
199fn parseObjectStaticLib(elf_file: *Elf, path: Path) Elf.ParseError!void {
200 const gpa = elf_file.base.comp.gpa;
201 const file_handles = &elf_file.file_handles;
202
203 const handle = try path.root_dir.handle.openFile(path.sub_path, .{});
204 const fh = try Elf.addFileHandle(gpa, file_handles, handle);
205
206 const index: File.Index = @intCast(try elf_file.files.addOne(gpa));
207 elf_file.files.set(index, .{ .object = .{
208 .path = .{
209 .root_dir = path.root_dir,
210 .sub_path = try gpa.dupe(u8, path.sub_path),
211 },
212 .file_handle = fh,
213 .index = index,
214 } });
215 try elf_file.objects.append(gpa, index);
216
217 const object = elf_file.file(index).?.object;
218 try object.parseAr(path, elf_file);
219}
220
221185fn claimUnresolved(elf_file: *Elf) void {
222186 if (elf_file.zigObjectPtr()) |zig_object| {
223187 zig_object.claimUnresolvedRelocatable(elf_file);