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 {...@@ -765,6 +765,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
765 const target = self.getTarget();765 const target = self.getTarget();
766 const debug_fmt_strip = comp.config.debug_format == .strip;766 const debug_fmt_strip = comp.config.debug_format == .strip;
767 const default_sym_version = self.default_sym_version;767 const default_sym_version = self.default_sym_version;
768 const is_static_lib = self.base.isStaticLib();
768769
769 if (comp.verbose_link) {770 if (comp.verbose_link) {
770 const argv = &self.dump_argv_list;771 const argv = &self.dump_argv_list;
...@@ -780,7 +781,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {...@@ -780,7 +781,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
780 .res => unreachable,781 .res => unreachable,
781 .dso_exact => @panic("TODO"),782 .dso_exact => @panic("TODO"),
782 .object => |obj| try parseObject(self, obj),783 .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),
784 .dso => |dso| try parseDso(gpa, diags, dso, &self.shared_objects, &self.files, target),785 .dso => |dso| try parseDso(gpa, diags, dso, &self.shared_objects, &self.files, target),
785 }786 }
786}787}
...@@ -823,17 +824,17 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod...@@ -823,17 +824,17 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
823824
824 if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid);825 if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid);
825826
827 if (module_obj_path) |path| openParseObjectReportingFailure(self, path);
828
826 switch (comp.config.output_mode) {829 switch (comp.config.output_mode) {
827 .Obj => return relocatable.flushObject(self, comp, module_obj_path),830 .Obj => return relocatable.flushObject(self, comp),
828 .Lib => switch (comp.config.link_mode) {831 .Lib => switch (comp.config.link_mode) {
829 .dynamic => {},832 .dynamic => {},
830 .static => return relocatable.flushStaticLib(self, comp, module_obj_path),833 .static => return relocatable.flushStaticLib(self, comp),
831 },834 },
832 .Exe => {},835 .Exe => {},
833 }836 }
834837
835 if (module_obj_path) |path| openParseObjectReportingFailure(self, path);
836
837 if (diags.hasErrors()) return error.FlushFailure;838 if (diags.hasErrors()) return error.FlushFailure;
838839
839 // If we haven't already, create a linker-generated input file comprising of840 // 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 {...@@ -1149,7 +1150,10 @@ fn parseObject(self: *Elf, obj: link.Input.Object) ParseError!void {
1149 try self.objects.append(gpa, index);1150 try self.objects.append(gpa, index);
11501151
1151 const object = self.file(index).?.object;1152 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 }
1153}1157}
11541158
1155fn parseArchive(1159fn parseArchive(
...@@ -1163,6 +1167,7 @@ fn parseArchive(...@@ -1163,6 +1167,7 @@ fn parseArchive(
1163 default_sym_version: elf.Versym,1167 default_sym_version: elf.Versym,
1164 objects: *std.ArrayListUnmanaged(File.Index),1168 objects: *std.ArrayListUnmanaged(File.Index),
1165 obj: link.Input.Object,1169 obj: link.Input.Object,
1170 is_static_lib: bool,
1166) ParseError!void {1171) ParseError!void {
1167 const tracy = trace(@src());1172 const tracy = trace(@src());
1168 defer tracy.end();1173 defer tracy.end();
...@@ -1171,13 +1176,17 @@ fn parseArchive(...@@ -1171,13 +1176,17 @@ fn parseArchive(
1171 var archive = try Archive.parse(gpa, diags, file_handles, obj.path, fh);1176 var archive = try Archive.parse(gpa, diags, file_handles, obj.path, fh);
1172 defer archive.deinit(gpa);1177 defer archive.deinit(gpa);
11731178
1179 const init_alive = if (is_static_lib) true else obj.must_link;
1180
1174 for (archive.objects) |extracted| {1181 for (archive.objects) |extracted| {
1175 const index: File.Index = @intCast(try files.addOne(gpa));1182 const index: File.Index = @intCast(try files.addOne(gpa));
1176 files.set(index, .{ .object = extracted });1183 files.set(index, .{ .object = extracted });
1177 const object = &files.items(.data)[index].object;1184 const object = &files.items(.data)[index].object;
1178 object.index = index;1185 object.index = index;
1179 object.alive = obj.must_link;1186 object.alive = init_alive;
1180 try object.parse(gpa, diags, obj.path, obj.file, first_eflags, target, debug_fmt_strip, default_sym_version);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);
1181 try objects.append(gpa, index);1190 try objects.append(gpa, index);
1182 }1191 }
1183}1192}
src/link/Elf/Object.zig+2-14
...@@ -69,13 +69,10 @@ pub fn parse(...@@ -69,13 +69,10 @@ pub fn parse(
69 /// For error reporting purposes only.69 /// For error reporting purposes only.
70 path: Path,70 path: Path,
71 handle: fs.File,71 handle: fs.File,
72 first_eflags: *?elf.Word,
73 target: std.Target,72 target: std.Target,
74 debug_fmt_strip: bool,73 debug_fmt_strip: bool,
75 default_sym_version: elf.Versym,74 default_sym_version: elf.Versym,
76) !void {75) !void {
77 try self.parseCommon(gpa, diags, path, handle, first_eflags, target);
78
79 // Append null input merge section76 // Append null input merge section
80 try self.input_merge_sections.append(gpa, .{});77 try self.input_merge_sections.append(gpa, .{});
81 // Allocate atom index 0 to null atom78 // Allocate atom index 0 to null atom
...@@ -95,14 +92,14 @@ pub fn parse(...@@ -95,14 +92,14 @@ pub fn parse(
95 }92 }
96}93}
9794
98fn parseCommon(95pub fn parseCommon(
99 self: *Object,96 self: *Object,
100 gpa: Allocator,97 gpa: Allocator,
101 diags: *Diags,98 diags: *Diags,
102 path: Path,99 path: Path,
103 handle: fs.File,100 handle: fs.File,
104 first_eflags: *?elf.Word,
105 target: std.Target,101 target: std.Target,
102 first_eflags: *?elf.Word,
106) !void {103) !void {
107 const offset = if (self.archive) |ar| ar.offset else 0;104 const offset = if (self.archive) |ar| ar.offset else 0;
108 const file_size = (try handle.stat()).size;105 const file_size = (try handle.stat()).size;
...@@ -1036,15 +1033,6 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {...@@ -1036,15 +1033,6 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
1036 }1033 }
1037}1034}
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
1048pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {1036pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {
1049 const comp = elf_file.base.comp;1037 const comp = elf_file.base.comp;
1050 const gpa = comp.gpa;1038 const gpa = comp.gpa;
src/link/Elf/relocatable.zig+2-38
...@@ -1,11 +1,7 @@...@@ -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 {
2 const gpa = comp.gpa;2 const gpa = comp.gpa;
3 const diags = &comp.link_diags;3 const diags = &comp.link_diags;
44
5 if (module_obj_path) |path| {
6 parseObjectStaticLibReportingFailure(elf_file, path);
7 }
8
9 if (diags.hasErrors()) return error.FlushFailure;5 if (diags.hasErrors()) return error.FlushFailure;
106
11 // First, we flush relocatable object file generated with our backends.7 // 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...@@ -134,11 +130,9 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path
134 if (diags.hasErrors()) return error.FlushFailure;130 if (diags.hasErrors()) return error.FlushFailure;
135}131}
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 {
138 const diags = &comp.link_diags;134 const diags = &comp.link_diags;
139135
140 if (module_obj_path) |path| elf_file.openParseObjectReportingFailure(path);
141
142 if (diags.hasErrors()) return error.FlushFailure;136 if (diags.hasErrors()) return error.FlushFailure;
143137
144 // Now, we are ready to resolve the symbols across all input files.138 // 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...@@ -188,36 +182,6 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) l
188 if (diags.hasErrors()) return error.FlushFailure;182 if (diags.hasErrors()) return error.FlushFailure;
189}183}
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
221fn claimUnresolved(elf_file: *Elf) void {185fn claimUnresolved(elf_file: *Elf) void {
222 if (elf_file.zigObjectPtr()) |zig_object| {186 if (elf_file.zigObjectPtr()) |zig_object| {
223 zig_object.claimUnresolvedRelocatable(elf_file);187 zig_object.claimUnresolvedRelocatable(elf_file);