| ... | ... | @@ -1041,9 +1041,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1041 | 1041 | } |
| 1042 | 1042 | |
| 1043 | 1043 | for (positionals.items) |obj| { |
| 1044 | | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1045 | | self.parsePositional(obj.path, obj.must_link, &parse_ctx) catch |err| |
| 1046 | | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1044 | self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) { |
| 1045 | error.MalformedObject, error.MalformedArchive, error.InvalidCpuArch => continue, // already reported |
| 1046 | else => |e| try self.reportParseError( |
| 1047 | obj.path, |
| 1048 | "unexpected error: parsing input file failed with error {s}", |
| 1049 | .{@errorName(e)}, |
| 1050 | ), |
| 1051 | }; |
| 1047 | 1052 | } |
| 1048 | 1053 | |
| 1049 | 1054 | var system_libs = std.ArrayList(SystemLib).init(arena); |
| ... | ... | @@ -1122,9 +1127,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1122 | 1127 | } |
| 1123 | 1128 | |
| 1124 | 1129 | for (system_libs.items) |lib| { |
| 1125 | | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1126 | | self.parseLibrary(lib, false, &parse_ctx) catch |err| |
| 1127 | | try self.handleAndReportParseError(lib.path, err, &parse_ctx); |
| 1130 | self.parseLibrary(lib, false) catch |err| switch (err) { |
| 1131 | error.MalformedObject, error.MalformedArchive, error.InvalidCpuArch => continue, // already reported |
| 1132 | else => |e| try self.reportParseError( |
| 1133 | lib.path, |
| 1134 | "unexpected error: parsing library failed with error {s}", |
| 1135 | .{@errorName(e)}, |
| 1136 | ), |
| 1137 | }; |
| 1128 | 1138 | } |
| 1129 | 1139 | |
| 1130 | 1140 | // Finally, as the last input objects we add compiler_rt and CSU postlude (if any). |
| ... | ... | @@ -1140,11 +1150,18 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1140 | 1150 | if (csu.crtn) |v| try positionals.append(.{ .path = v }); |
| 1141 | 1151 | |
| 1142 | 1152 | for (positionals.items) |obj| { |
| 1143 | | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1144 | | self.parsePositional(obj.path, obj.must_link, &parse_ctx) catch |err| |
| 1145 | | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1153 | self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) { |
| 1154 | error.MalformedObject, error.MalformedArchive, error.InvalidCpuArch => continue, // already reported |
| 1155 | else => |e| try self.reportParseError( |
| 1156 | obj.path, |
| 1157 | "unexpected error: parsing input file failed with error {s}", |
| 1158 | .{@errorName(e)}, |
| 1159 | ), |
| 1160 | }; |
| 1146 | 1161 | } |
| 1147 | 1162 | |
| 1163 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1164 | |
| 1148 | 1165 | // Init all objects |
| 1149 | 1166 | for (self.objects.items) |index| { |
| 1150 | 1167 | try self.file(index).?.object.init(self); |
| ... | ... | @@ -1153,6 +1170,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1153 | 1170 | try self.file(index).?.shared_object.init(self); |
| 1154 | 1171 | } |
| 1155 | 1172 | |
| 1173 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1174 | |
| 1156 | 1175 | // Dedup shared objects |
| 1157 | 1176 | { |
| 1158 | 1177 | var seen_dsos = std.StringHashMap(void).init(gpa); |
| ... | ... | @@ -1279,6 +1298,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1279 | 1298 | self.error_flags.no_entry_point_found = false; |
| 1280 | 1299 | try self.writeElfHeader(); |
| 1281 | 1300 | } |
| 1301 | |
| 1302 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1282 | 1303 | } |
| 1283 | 1304 | |
| 1284 | 1305 | pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void { |
| ... | ... | @@ -1300,11 +1321,18 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 1300 | 1321 | if (module_obj_path) |path| try positionals.append(.{ .path = path }); |
| 1301 | 1322 | |
| 1302 | 1323 | for (positionals.items) |obj| { |
| 1303 | | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1304 | | self.parsePositional(obj.path, obj.must_link, &parse_ctx) catch |err| |
| 1305 | | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1324 | self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) { |
| 1325 | error.MalformedObject, error.MalformedArchive, error.InvalidCpuArch => continue, // already reported |
| 1326 | else => |e| try self.reportParseError( |
| 1327 | obj.path, |
| 1328 | "unexpected error: parsing input file failed with error {s}", |
| 1329 | .{@errorName(e)}, |
| 1330 | ), |
| 1331 | }; |
| 1306 | 1332 | } |
| 1307 | 1333 | |
| 1334 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1335 | |
| 1308 | 1336 | // First, we flush relocatable object file generated with our backends. |
| 1309 | 1337 | if (self.zigObjectPtr()) |zig_object| { |
| 1310 | 1338 | zig_object.resolveSymbols(self); |
| ... | ... | @@ -1316,6 +1344,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 1316 | 1344 | try zig_object.addAtomsToRelaSections(self); |
| 1317 | 1345 | try self.updateSectionSizesObject(); |
| 1318 | 1346 | |
| 1347 | try self.allocateAllocSectionsObject(); |
| 1319 | 1348 | try self.allocateNonAllocSections(); |
| 1320 | 1349 | |
| 1321 | 1350 | if (build_options.enable_logging) { |
| ... | ... | @@ -1325,14 +1354,15 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 1325 | 1354 | try self.writeSyntheticSectionsObject(); |
| 1326 | 1355 | try self.writeShdrTable(); |
| 1327 | 1356 | try self.writeElfHeader(); |
| 1357 | |
| 1358 | // TODO we can avoid reading in the file contents we just wrote if we give the linker |
| 1359 | // ability to write directly to a buffer. |
| 1360 | try zig_object.readFileContents(self); |
| 1328 | 1361 | } |
| 1329 | 1362 | |
| 1330 | 1363 | var files = std.ArrayList(File.Index).init(gpa); |
| 1331 | 1364 | defer files.deinit(); |
| 1332 | 1365 | try files.ensureTotalCapacityPrecise(self.objects.items.len + 1); |
| 1333 | | // Note to self: we currently must have ZigObject written out first as we write the object |
| 1334 | | // file into the same file descriptor and then re-read its contents. |
| 1335 | | // TODO implement writing ZigObject to a buffer instead of file. |
| 1336 | 1366 | if (self.zigObjectPtr()) |zig_object| files.appendAssumeCapacity(zig_object.index); |
| 1337 | 1367 | for (self.objects.items) |index| files.appendAssumeCapacity(index); |
| 1338 | 1368 | |
| ... | ... | @@ -1353,7 +1383,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 1353 | 1383 | for (files.items) |index| { |
| 1354 | 1384 | const file_ptr = self.file(index).?; |
| 1355 | 1385 | try file_ptr.updateArStrtab(gpa, &ar_strtab); |
| 1356 | | file_ptr.updateArSize(self); |
| 1386 | file_ptr.updateArSize(); |
| 1357 | 1387 | } |
| 1358 | 1388 | |
| 1359 | 1389 | // Update file offsets of contributing objects. |
| ... | ... | @@ -1405,13 +1435,15 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 1405 | 1435 | // Write object files |
| 1406 | 1436 | for (files.items) |index| { |
| 1407 | 1437 | if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0); |
| 1408 | | try self.file(index).?.writeAr(self, buffer.writer()); |
| 1438 | try self.file(index).?.writeAr(buffer.writer()); |
| 1409 | 1439 | } |
| 1410 | 1440 | |
| 1411 | 1441 | assert(buffer.items.len == total_size); |
| 1412 | 1442 | |
| 1413 | 1443 | try self.base.file.?.setEndPos(total_size); |
| 1414 | 1444 | try self.base.file.?.pwriteAll(buffer.items, 0); |
| 1445 | |
| 1446 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1415 | 1447 | } |
| 1416 | 1448 | |
| 1417 | 1449 | pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void { |
| ... | ... | @@ -1432,16 +1464,25 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) |
| 1432 | 1464 | if (module_obj_path) |path| try positionals.append(.{ .path = path }); |
| 1433 | 1465 | |
| 1434 | 1466 | for (positionals.items) |obj| { |
| 1435 | | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1436 | | self.parsePositional(obj.path, obj.must_link, &parse_ctx) catch |err| |
| 1437 | | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1467 | self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) { |
| 1468 | error.MalformedObject, error.MalformedArchive, error.InvalidCpuArch => continue, // already reported |
| 1469 | else => |e| try self.reportParseError( |
| 1470 | obj.path, |
| 1471 | "unexpected error: parsing input file failed with error {s}", |
| 1472 | .{@errorName(e)}, |
| 1473 | ), |
| 1474 | }; |
| 1438 | 1475 | } |
| 1439 | 1476 | |
| 1477 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1478 | |
| 1440 | 1479 | // Init all objects |
| 1441 | 1480 | for (self.objects.items) |index| { |
| 1442 | 1481 | try self.file(index).?.object.init(self); |
| 1443 | 1482 | } |
| 1444 | 1483 | |
| 1484 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1485 | |
| 1445 | 1486 | // Now, we are ready to resolve the symbols across all input files. |
| 1446 | 1487 | // We will first resolve the files in the ZigObject, next in the parsed |
| 1447 | 1488 | // input Object files. |
| ... | ... | @@ -1473,6 +1514,8 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) |
| 1473 | 1514 | try self.writeSyntheticSectionsObject(); |
| 1474 | 1515 | try self.writeShdrTable(); |
| 1475 | 1516 | try self.writeElfHeader(); |
| 1517 | |
| 1518 | if (self.misc_errors.items.len > 0) return error.FlushFailure; |
| 1476 | 1519 | } |
| 1477 | 1520 | |
| 1478 | 1521 | /// --verbose-link output |
| ... | ... | @@ -1760,7 +1803,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1760 | 1803 | } |
| 1761 | 1804 | |
| 1762 | 1805 | const ParseError = error{ |
| 1763 | | UnknownFileType, |
| 1806 | MalformedObject, |
| 1807 | MalformedArchive, |
| 1764 | 1808 | InvalidCpuArch, |
| 1765 | 1809 | OutOfMemory, |
| 1766 | 1810 | Overflow, |
| ... | ... | @@ -1771,34 +1815,30 @@ const ParseError = error{ |
| 1771 | 1815 | InvalidCharacter, |
| 1772 | 1816 | } || LdScript.Error || std.os.AccessError || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError; |
| 1773 | 1817 | |
| 1774 | | fn parsePositional(self: *Elf, path: []const u8, must_link: bool, ctx: *ParseErrorCtx) ParseError!void { |
| 1818 | fn parsePositional(self: *Elf, path: []const u8, must_link: bool) ParseError!void { |
| 1775 | 1819 | const tracy = trace(@src()); |
| 1776 | 1820 | defer tracy.end(); |
| 1777 | 1821 | if (try Object.isObject(path)) { |
| 1778 | | try self.parseObject(path, ctx); |
| 1822 | try self.parseObject(path); |
| 1779 | 1823 | } else { |
| 1780 | | try self.parseLibrary(.{ .path = path }, must_link, ctx); |
| 1824 | try self.parseLibrary(.{ .path = path }, must_link); |
| 1781 | 1825 | } |
| 1782 | 1826 | } |
| 1783 | 1827 | |
| 1784 | | fn parseLibrary(self: *Elf, lib: SystemLib, must_link: bool, ctx: *ParseErrorCtx) ParseError!void { |
| 1828 | fn parseLibrary(self: *Elf, lib: SystemLib, must_link: bool) ParseError!void { |
| 1785 | 1829 | const tracy = trace(@src()); |
| 1786 | 1830 | defer tracy.end(); |
| 1787 | 1831 | |
| 1788 | 1832 | if (try Archive.isArchive(lib.path)) { |
| 1789 | | try self.parseArchive(lib.path, must_link, ctx); |
| 1833 | try self.parseArchive(lib.path, must_link); |
| 1790 | 1834 | } else if (try SharedObject.isSharedObject(lib.path)) { |
| 1791 | | try self.parseSharedObject(lib, ctx); |
| 1835 | try self.parseSharedObject(lib); |
| 1792 | 1836 | } else { |
| 1793 | | // TODO if the script has a top-level comment identifying it as GNU ld script, |
| 1794 | | // then report parse errors. Otherwise return UnknownFileType. |
| 1795 | | self.parseLdScript(lib, ctx) catch |err| switch (err) { |
| 1796 | | else => return error.UnknownFileType, |
| 1797 | | }; |
| 1837 | try self.parseLdScript(lib); |
| 1798 | 1838 | } |
| 1799 | 1839 | } |
| 1800 | 1840 | |
| 1801 | | fn parseObject(self: *Elf, path: []const u8, ctx: *ParseErrorCtx) ParseError!void { |
| 1841 | fn parseObject(self: *Elf, path: []const u8) ParseError!void { |
| 1802 | 1842 | const tracy = trace(@src()); |
| 1803 | 1843 | defer tracy.end(); |
| 1804 | 1844 | |
| ... | ... | @@ -1816,12 +1856,9 @@ fn parseObject(self: *Elf, path: []const u8, ctx: *ParseErrorCtx) ParseError!voi |
| 1816 | 1856 | |
| 1817 | 1857 | const object = self.file(index).?.object; |
| 1818 | 1858 | try object.parse(self); |
| 1819 | | |
| 1820 | | ctx.detected_cpu_arch = object.header.?.e_machine.toTargetCpuArch().?; |
| 1821 | | if (ctx.detected_cpu_arch != self.base.options.target.cpu.arch) return error.InvalidCpuArch; |
| 1822 | 1859 | } |
| 1823 | 1860 | |
| 1824 | | fn parseArchive(self: *Elf, path: []const u8, must_link: bool, ctx: *ParseErrorCtx) ParseError!void { |
| 1861 | fn parseArchive(self: *Elf, path: []const u8, must_link: bool) ParseError!void { |
| 1825 | 1862 | const tracy = trace(@src()); |
| 1826 | 1863 | defer tracy.end(); |
| 1827 | 1864 | |
| ... | ... | @@ -1844,13 +1881,10 @@ fn parseArchive(self: *Elf, path: []const u8, must_link: bool, ctx: *ParseErrorC |
| 1844 | 1881 | object.alive = must_link; |
| 1845 | 1882 | try object.parse(self); |
| 1846 | 1883 | try self.objects.append(gpa, index); |
| 1847 | | |
| 1848 | | ctx.detected_cpu_arch = object.header.?.e_machine.toTargetCpuArch().?; |
| 1849 | | if (ctx.detected_cpu_arch != self.base.options.target.cpu.arch) return error.InvalidCpuArch; |
| 1850 | 1884 | } |
| 1851 | 1885 | } |
| 1852 | 1886 | |
| 1853 | | fn parseSharedObject(self: *Elf, lib: SystemLib, ctx: *ParseErrorCtx) ParseError!void { |
| 1887 | fn parseSharedObject(self: *Elf, lib: SystemLib) ParseError!void { |
| 1854 | 1888 | const tracy = trace(@src()); |
| 1855 | 1889 | defer tracy.end(); |
| 1856 | 1890 | |
| ... | ... | @@ -1870,12 +1904,9 @@ fn parseSharedObject(self: *Elf, lib: SystemLib, ctx: *ParseErrorCtx) ParseError |
| 1870 | 1904 | |
| 1871 | 1905 | const shared_object = self.file(index).?.shared_object; |
| 1872 | 1906 | try shared_object.parse(self); |
| 1873 | | |
| 1874 | | ctx.detected_cpu_arch = shared_object.header.?.e_machine.toTargetCpuArch().?; |
| 1875 | | if (ctx.detected_cpu_arch != self.base.options.target.cpu.arch) return error.InvalidCpuArch; |
| 1876 | 1907 | } |
| 1877 | 1908 | |
| 1878 | | fn parseLdScript(self: *Elf, lib: SystemLib, ctx: *ParseErrorCtx) ParseError!void { |
| 1909 | fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1879 | 1910 | const tracy = trace(@src()); |
| 1880 | 1911 | defer tracy.end(); |
| 1881 | 1912 | |
| ... | ... | @@ -1885,15 +1916,10 @@ fn parseLdScript(self: *Elf, lib: SystemLib, ctx: *ParseErrorCtx) ParseError!voi |
| 1885 | 1916 | const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32)); |
| 1886 | 1917 | defer gpa.free(data); |
| 1887 | 1918 | |
| 1888 | | var script = LdScript{}; |
| 1919 | var script = LdScript{ .path = lib.path }; |
| 1889 | 1920 | defer script.deinit(gpa); |
| 1890 | 1921 | try script.parse(data, self); |
| 1891 | 1922 | |
| 1892 | | if (script.cpu_arch) |cpu_arch| { |
| 1893 | | ctx.detected_cpu_arch = cpu_arch; |
| 1894 | | if (ctx.detected_cpu_arch != self.base.options.target.cpu.arch) return error.InvalidCpuArch; |
| 1895 | | } |
| 1896 | | |
| 1897 | 1923 | const lib_dirs = self.base.options.lib_dirs; |
| 1898 | 1924 | |
| 1899 | 1925 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| ... | ... | @@ -1947,11 +1973,17 @@ fn parseLdScript(self: *Elf, lib: SystemLib, ctx: *ParseErrorCtx) ParseError!voi |
| 1947 | 1973 | } |
| 1948 | 1974 | |
| 1949 | 1975 | const full_path = test_path.items; |
| 1950 | | var scr_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1951 | 1976 | self.parseLibrary(.{ |
| 1952 | 1977 | .needed = scr_obj.needed, |
| 1953 | 1978 | .path = full_path, |
| 1954 | | }, false, &scr_ctx) catch |err| try self.handleAndReportParseError(full_path, err, &scr_ctx); |
| 1979 | }, false) catch |err| switch (err) { |
| 1980 | error.MalformedObject, error.MalformedArchive, error.InvalidCpuArch => continue, // already reported |
| 1981 | else => |e| try self.reportParseError( |
| 1982 | full_path, |
| 1983 | "unexpected error: parsing library failed with error {s}", |
| 1984 | .{@errorName(e)}, |
| 1985 | ), |
| 1986 | }; |
| 1955 | 1987 | } |
| 1956 | 1988 | } |
| 1957 | 1989 | |
| ... | ... | @@ -2177,7 +2209,7 @@ fn scanRelocs(self: *Elf) !void { |
| 2177 | 2209 | try object.scanRelocs(self, &undefs); |
| 2178 | 2210 | } |
| 2179 | 2211 | |
| 2180 | | try self.reportUndefined(&undefs); |
| 2212 | try self.reportUndefinedSymbols(&undefs); |
| 2181 | 2213 | |
| 2182 | 2214 | for (self.symbols.items, 0..) |*sym, i| { |
| 2183 | 2215 | const index = @as(u32, @intCast(i)); |
| ... | ... | @@ -2789,7 +2821,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2789 | 2821 | })); |
| 2790 | 2822 | } else { |
| 2791 | 2823 | self.error_flags.missing_libc = true; |
| 2792 | | return error.FlushFailure; |
| 2793 | 2824 | } |
| 2794 | 2825 | } |
| 2795 | 2826 | } |
| ... | ... | @@ -2945,6 +2976,7 @@ fn writeShdrTable(self: *Elf) !void { |
| 2945 | 2976 | defer gpa.free(buf); |
| 2946 | 2977 | |
| 2947 | 2978 | for (buf, 0..) |*shdr, i| { |
| 2979 | assert(self.shdrs.items[i].sh_offset != math.maxInt(u64)); |
| 2948 | 2980 | shdr.* = shdrTo32(self.shdrs.items[i]); |
| 2949 | 2981 | if (foreign_endian) { |
| 2950 | 2982 | mem.byteSwapAllFields(elf.Elf32_Shdr, shdr); |
| ... | ... | @@ -2957,6 +2989,7 @@ fn writeShdrTable(self: *Elf) !void { |
| 2957 | 2989 | defer gpa.free(buf); |
| 2958 | 2990 | |
| 2959 | 2991 | for (buf, 0..) |*shdr, i| { |
| 2992 | assert(self.shdrs.items[i].sh_offset != math.maxInt(u64)); |
| 2960 | 2993 | shdr.* = self.shdrs.items[i]; |
| 2961 | 2994 | if (foreign_endian) { |
| 2962 | 2995 | mem.byteSwapAllFields(elf.Elf64_Shdr, shdr); |
| ... | ... | @@ -3007,6 +3040,8 @@ fn writePhdrTable(self: *Elf) !void { |
| 3007 | 3040 | } |
| 3008 | 3041 | |
| 3009 | 3042 | fn writeElfHeader(self: *Elf) !void { |
| 3043 | if (self.misc_errors.items.len > 0) return; // We had errors, so skip flushing to render the output unusable |
| 3044 | |
| 3010 | 3045 | var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined; |
| 3011 | 3046 | |
| 3012 | 3047 | var index: usize = 0; |
| ... | ... | @@ -4740,7 +4775,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4740 | 4775 | try self.base.file.?.pwriteAll(buffer, sh_offset); |
| 4741 | 4776 | } |
| 4742 | 4777 | |
| 4743 | | try self.reportUndefined(&undefs); |
| 4778 | try self.reportUndefinedSymbols(&undefs); |
| 4744 | 4779 | } |
| 4745 | 4780 | |
| 4746 | 4781 | fn writeAtomsObject(self: *Elf) !void { |
| ... | ... | @@ -6003,7 +6038,7 @@ pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 { |
| 6003 | 6038 | return off; |
| 6004 | 6039 | } |
| 6005 | 6040 | |
| 6006 | | fn reportUndefined(self: *Elf, undefs: anytype) !void { |
| 6041 | fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void { |
| 6007 | 6042 | const gpa = self.base.allocator; |
| 6008 | 6043 | const max_notes = 4; |
| 6009 | 6044 | |
| ... | ... | @@ -6045,41 +6080,26 @@ fn reportMissingLibraryError( |
| 6045 | 6080 | } |
| 6046 | 6081 | } |
| 6047 | 6082 | |
| 6048 | | const ParseErrorCtx = struct { |
| 6049 | | detected_cpu_arch: std.Target.Cpu.Arch, |
| 6050 | | }; |
| 6051 | | |
| 6052 | | fn handleAndReportParseError( |
| 6083 | pub fn reportParseError( |
| 6053 | 6084 | self: *Elf, |
| 6054 | 6085 | path: []const u8, |
| 6055 | | err: ParseError, |
| 6056 | | ctx: *const ParseErrorCtx, |
| 6086 | comptime format: []const u8, |
| 6087 | args: anytype, |
| 6057 | 6088 | ) error{OutOfMemory}!void { |
| 6058 | | const cpu_arch = self.base.options.target.cpu.arch; |
| 6059 | | switch (err) { |
| 6060 | | error.UnknownFileType => try self.reportParseError(path, "unknown file type", .{}), |
| 6061 | | error.InvalidCpuArch => try self.reportParseError( |
| 6062 | | path, |
| 6063 | | "invalid cpu architecture: expected '{s}', but found '{s}'", |
| 6064 | | .{ @tagName(cpu_arch), @tagName(ctx.detected_cpu_arch) }, |
| 6065 | | ), |
| 6066 | | else => |e| try self.reportParseError( |
| 6067 | | path, |
| 6068 | | "unexpected error: parsing object failed with error {s}", |
| 6069 | | .{@errorName(e)}, |
| 6070 | | ), |
| 6071 | | } |
| 6072 | | } |
| 6073 | | |
| 6074 | | fn reportParseError( |
| 6089 | var err = try self.addErrorWithNotes(1); |
| 6090 | try err.addMsg(self, format, args); |
| 6091 | try err.addNote(self, "while parsing {s}", .{path}); |
| 6092 | } |
| 6093 | |
| 6094 | pub fn reportParseError2( |
| 6075 | 6095 | self: *Elf, |
| 6076 | | path: []const u8, |
| 6096 | file_index: File.Index, |
| 6077 | 6097 | comptime format: []const u8, |
| 6078 | 6098 | args: anytype, |
| 6079 | 6099 | ) error{OutOfMemory}!void { |
| 6080 | 6100 | var err = try self.addErrorWithNotes(1); |
| 6081 | 6101 | try err.addMsg(self, format, args); |
| 6082 | | try err.addNote(self, "while parsing {s}", .{path}); |
| 6102 | try err.addNote(self, "while parsing {}", .{self.file(file_index).?.fmtPath()}); |
| 6083 | 6103 | } |
| 6084 | 6104 | |
| 6085 | 6105 | const FormatShdrCtx = struct { |