| author | |
| committer | |
| log | de0f7fcf526312088e4b373c6ed7436427080087 |
| tree | 9793bf83f7c1eaf893754af273b8fbd6ea772796 |
| parent | 12f3a7c3c202475c67b639c369829a0390cfb0f8 |
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 | 765 | const target = self.getTarget(); |
| 766 | 766 | const debug_fmt_strip = comp.config.debug_format == .strip; |
| 767 | 767 | const default_sym_version = self.default_sym_version; |
| 768 | const is_static_lib = self.base.isStaticLib(); | |
| 768 | 769 | |
| 769 | 770 | if (comp.verbose_link) { |
| 770 | 771 | const argv = &self.dump_argv_list; |
| ... | ... | @@ -780,7 +781,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { |
| 780 | 781 | .res => unreachable, |
| 781 | 782 | .dso_exact => @panic("TODO"), |
| 782 | 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 | 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 | 824 | |
| 824 | 825 | if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid); |
| 825 | 826 | |
| 827 | if (module_obj_path) |path| openParseObjectReportingFailure(self, path); | |
| 828 | ||
| 826 | 829 | switch (comp.config.output_mode) { |
| 827 | .Obj => return relocatable.flushObject(self, comp, module_obj_path), | |
| 830 | .Obj => return relocatable.flushObject(self, comp), | |
| 828 | 831 | .Lib => switch (comp.config.link_mode) { |
| 829 | 832 | .dynamic => {}, |
| 830 | .static => return relocatable.flushStaticLib(self, comp, module_obj_path), | |
| 833 | .static => return relocatable.flushStaticLib(self, comp), | |
| 831 | 834 | }, |
| 832 | 835 | .Exe => {}, |
| 833 | 836 | } |
| 834 | 837 | |
| 835 | if (module_obj_path) |path| openParseObjectReportingFailure(self, path); | |
| 836 | ||
| 837 | 838 | if (diags.hasErrors()) return error.FlushFailure; |
| 838 | 839 | |
| 839 | 840 | // 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 | 1150 | try self.objects.append(gpa, index); |
| 1150 | 1151 | |
| 1151 | 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 | } |
| 1154 | 1158 | |
| 1155 | 1159 | fn parseArchive( |
| ... | ... | @@ -1163,6 +1167,7 @@ fn parseArchive( |
| 1163 | 1167 | default_sym_version: elf.Versym, |
| 1164 | 1168 | objects: *std.ArrayListUnmanaged(File.Index), |
| 1165 | 1169 | obj: link.Input.Object, |
| 1170 | is_static_lib: bool, | |
| 1166 | 1171 | ) ParseError!void { |
| 1167 | 1172 | const tracy = trace(@src()); |
| 1168 | 1173 | defer tracy.end(); |
| ... | ... | @@ -1171,13 +1176,17 @@ fn parseArchive( |
| 1171 | 1176 | var archive = try Archive.parse(gpa, diags, file_handles, obj.path, fh); |
| 1172 | 1177 | defer archive.deinit(gpa); |
| 1173 | 1178 | |
| 1179 | const init_alive = if (is_static_lib) true else obj.must_link; | |
| 1180 | ||
| 1174 | 1181 | for (archive.objects) |extracted| { |
| 1175 | 1182 | const index: File.Index = @intCast(try files.addOne(gpa)); |
| 1176 | 1183 | files.set(index, .{ .object = extracted }); |
| 1177 | 1184 | const object = &files.items(.data)[index].object; |
| 1178 | 1185 | 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); | |
| 1181 | 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 | 69 | /// For error reporting purposes only. |
| 70 | 70 | path: Path, |
| 71 | 71 | handle: fs.File, |
| 72 | first_eflags: *?elf.Word, | |
| 73 | 72 | target: std.Target, |
| 74 | 73 | debug_fmt_strip: bool, |
| 75 | 74 | default_sym_version: elf.Versym, |
| 76 | 75 | ) !void { |
| 77 | try self.parseCommon(gpa, diags, path, handle, first_eflags, target); | |
| 78 | ||
| 79 | 76 | // Append null input merge section |
| 80 | 77 | try self.input_merge_sections.append(gpa, .{}); |
| 81 | 78 | // Allocate atom index 0 to null atom |
| ... | ... | @@ -95,14 +92,14 @@ pub fn parse( |
| 95 | 92 | } |
| 96 | 93 | } |
| 97 | 94 | |
| 98 | fn parseCommon( | |
| 95 | pub fn parseCommon( | |
| 99 | 96 | self: *Object, |
| 100 | 97 | gpa: Allocator, |
| 101 | 98 | diags: *Diags, |
| 102 | 99 | path: Path, |
| 103 | 100 | handle: fs.File, |
| 104 | first_eflags: *?elf.Word, | |
| 105 | 101 | target: std.Target, |
| 102 | first_eflags: *?elf.Word, | |
| 106 | 103 | ) !void { |
| 107 | 104 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 108 | 105 | const file_size = (try handle.stat()).size; |
| ... | ... | @@ -1036,15 +1033,6 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1036 | 1033 | } |
| 1037 | 1034 | } |
| 1038 | 1035 | |
| 1039 | pub 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 | ||
| 1048 | 1036 | pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void { |
| 1049 | 1037 | const comp = elf_file.base.comp; |
| 1050 | 1038 | const gpa = comp.gpa; |
src/link/Elf/relocatable.zig+2-38| ... | ... | @@ -1,11 +1,7 @@ |
| 1 | pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { | |
| 1 | pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void { | |
| 2 | 2 | const gpa = comp.gpa; |
| 3 | 3 | const diags = &comp.link_diags; |
| 4 | 4 | |
| 5 | if (module_obj_path) |path| { | |
| 6 | parseObjectStaticLibReportingFailure(elf_file, path); | |
| 7 | } | |
| 8 | ||
| 9 | 5 | if (diags.hasErrors()) return error.FlushFailure; |
| 10 | 6 | |
| 11 | 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 | 130 | if (diags.hasErrors()) return error.FlushFailure; |
| 135 | 131 | } |
| 136 | 132 | |
| 137 | pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { | |
| 133 | pub fn flushObject(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void { | |
| 138 | 134 | const diags = &comp.link_diags; |
| 139 | 135 | |
| 140 | if (module_obj_path) |path| elf_file.openParseObjectReportingFailure(path); | |
| 141 | ||
| 142 | 136 | if (diags.hasErrors()) return error.FlushFailure; |
| 143 | 137 | |
| 144 | 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 | 182 | if (diags.hasErrors()) return error.FlushFailure; |
| 189 | 183 | } |
| 190 | 184 | |
| 191 | fn 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 | ||
| 199 | fn 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 | ||
| 221 | 185 | fn claimUnresolved(elf_file: *Elf) void { |
| 222 | 186 | if (elf_file.zigObjectPtr()) |zig_object| { |
| 223 | 187 | zig_object.claimUnresolvedRelocatable(elf_file); |