authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-12-05 14:08:01+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-12-05 14:08:04+01:00
log52959bba7cdfc763c192d4a713b810fda80ccd02
treea6ee6806164d9773439d2c1b534f1e0369999318
parent2e1dd1e554c9f557165520eba6199325b85c2d03

elf: re-instate basic error reporting for LD script parser


4 files changed, 36 insertions(+), 41 deletions(-)

src/link/Elf.zig+14-18
...@@ -1042,7 +1042,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1042,7 +1042,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10421042
1043 for (positionals.items) |obj| {1043 for (positionals.items) |obj| {
1044 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {1044 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1045 error.LinkFail, error.InvalidCpuArch => {}, // already reported1045 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
1046 else => |e| try self.reportParseError(1046 else => |e| try self.reportParseError(
1047 obj.path,1047 obj.path,
1048 "unexpected error: parsing input file failed with error {s}",1048 "unexpected error: parsing input file failed with error {s}",
...@@ -1128,7 +1128,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1128,7 +1128,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11281128
1129 for (system_libs.items) |lib| {1129 for (system_libs.items) |lib| {
1130 self.parseLibrary(lib, false) catch |err| switch (err) {1130 self.parseLibrary(lib, false) catch |err| switch (err) {
1131 error.LinkFail, error.InvalidCpuArch => {}, // already reported1131 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
1132 else => |e| try self.reportParseError(1132 else => |e| try self.reportParseError(
1133 lib.path,1133 lib.path,
1134 "unexpected error: parsing library failed with error {s}",1134 "unexpected error: parsing library failed with error {s}",
...@@ -1151,7 +1151,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1151,7 +1151,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11511151
1152 for (positionals.items) |obj| {1152 for (positionals.items) |obj| {
1153 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {1153 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1154 error.LinkFail, error.InvalidCpuArch => {}, // already reported1154 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
1155 else => |e| try self.reportParseError(1155 else => |e| try self.reportParseError(
1156 obj.path,1156 obj.path,
1157 "unexpected error: parsing input file failed with error {s}",1157 "unexpected error: parsing input file failed with error {s}",
...@@ -1316,7 +1316,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const...@@ -1316,7 +1316,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const
13161316
1317 for (positionals.items) |obj| {1317 for (positionals.items) |obj| {
1318 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {1318 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1319 error.LinkFail, error.InvalidCpuArch => {}, // already reported1319 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
1320 else => |e| try self.reportParseError(1320 else => |e| try self.reportParseError(
1321 obj.path,1321 obj.path,
1322 "unexpected error: parsing input file failed with error {s}",1322 "unexpected error: parsing input file failed with error {s}",
...@@ -1453,7 +1453,7 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8)...@@ -1453,7 +1453,7 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8)
14531453
1454 for (positionals.items) |obj| {1454 for (positionals.items) |obj| {
1455 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {1455 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1456 error.LinkFail, error.InvalidCpuArch => {}, // already reported1456 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
1457 else => |e| try self.reportParseError(1457 else => |e| try self.reportParseError(
1458 obj.path,1458 obj.path,
1459 "unexpected error: parsing input file failed with error {s}",1459 "unexpected error: parsing input file failed with error {s}",
...@@ -1785,8 +1785,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {...@@ -1785,8 +1785,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
1785}1785}
17861786
1787const ParseError = error{1787const ParseError = error{
1788 LinkFail,1788 MalformedObject,
1789 UnknownFileType,1789 MalformedArchive,
1790 InvalidCpuArch,1790 InvalidCpuArch,
1791 OutOfMemory,1791 OutOfMemory,
1792 Overflow,1792 Overflow,
...@@ -1816,11 +1816,7 @@ fn parseLibrary(self: *Elf, lib: SystemLib, must_link: bool) ParseError!void {...@@ -1816,11 +1816,7 @@ fn parseLibrary(self: *Elf, lib: SystemLib, must_link: bool) ParseError!void {
1816 } else if (try SharedObject.isSharedObject(lib.path)) {1816 } else if (try SharedObject.isSharedObject(lib.path)) {
1817 try self.parseSharedObject(lib);1817 try self.parseSharedObject(lib);
1818 } else {1818 } else {
1819 // TODO if the script has a top-level comment identifying it as GNU ld script,1819 try self.parseLdScript(lib);
1820 // then report parse errors. Otherwise return UnknownFileType.
1821 self.parseLdScript(lib) catch |err| switch (err) {
1822 else => return error.UnknownFileType,
1823 };
1824 }1820 }
1825}1821}
18261822
...@@ -1902,7 +1898,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {...@@ -1902,7 +1898,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
1902 const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));1898 const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));
1903 defer gpa.free(data);1899 defer gpa.free(data);
19041900
1905 var script = LdScript{};1901 var script = LdScript{ .path = lib.path };
1906 defer script.deinit(gpa);1902 defer script.deinit(gpa);
1907 try script.parse(data, self);1903 try script.parse(data, self);
19081904
...@@ -1963,7 +1959,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {...@@ -1963,7 +1959,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
1963 .needed = scr_obj.needed,1959 .needed = scr_obj.needed,
1964 .path = full_path,1960 .path = full_path,
1965 }, false) catch |err| switch (err) {1961 }, false) catch |err| switch (err) {
1966 error.LinkFail, error.InvalidCpuArch => {}, // already reported1962 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
1967 else => |e| try self.reportParseError(1963 else => |e| try self.reportParseError(
1968 full_path,1964 full_path,
1969 "unexpected error: parsing library failed with error {s}",1965 "unexpected error: parsing library failed with error {s}",
...@@ -2195,7 +2191,7 @@ fn scanRelocs(self: *Elf) !void {...@@ -2195,7 +2191,7 @@ fn scanRelocs(self: *Elf) !void {
2195 try object.scanRelocs(self, &undefs);2191 try object.scanRelocs(self, &undefs);
2196 }2192 }
21972193
2198 try self.reportUndefined(&undefs);2194 try self.reportUndefinedSymbols(&undefs);
21992195
2200 for (self.symbols.items, 0..) |*sym, i| {2196 for (self.symbols.items, 0..) |*sym, i| {
2201 const index = @as(u32, @intCast(i));2197 const index = @as(u32, @intCast(i));
...@@ -4760,7 +4756,7 @@ fn writeAtoms(self: *Elf) !void {...@@ -4760,7 +4756,7 @@ fn writeAtoms(self: *Elf) !void {
4760 try self.base.file.?.pwriteAll(buffer, sh_offset);4756 try self.base.file.?.pwriteAll(buffer, sh_offset);
4761 }4757 }
47624758
4763 try self.reportUndefined(&undefs);4759 try self.reportUndefinedSymbols(&undefs);
4764}4760}
47654761
4766fn writeAtomsObject(self: *Elf) !void {4762fn writeAtomsObject(self: *Elf) !void {
...@@ -6023,7 +6019,7 @@ pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 {...@@ -6023,7 +6019,7 @@ pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 {
6023 return off;6019 return off;
6024}6020}
60256021
6026fn reportUndefined(self: *Elf, undefs: anytype) !void {6022fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
6027 const gpa = self.base.allocator;6023 const gpa = self.base.allocator;
6028 const max_notes = 4;6024 const max_notes = 4;
60296025
...@@ -6065,7 +6061,7 @@ fn reportMissingLibraryError(...@@ -6065,7 +6061,7 @@ fn reportMissingLibraryError(
6065 }6061 }
6066}6062}
60676063
6068fn reportParseError(6064pub fn reportParseError(
6069 self: *Elf,6065 self: *Elf,
6070 path: []const u8,6066 path: []const u8,
6071 comptime format: []const u8,6067 comptime format: []const u8,
src/link/Elf/LdScript.zig+18-19
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1path: []const u8,
1cpu_arch: ?std.Target.Cpu.Arch = null,2cpu_arch: ?std.Target.Cpu.Arch = null,
2args: std.ArrayListUnmanaged(Elf.SystemLib) = .{},3args: std.ArrayListUnmanaged(Elf.SystemLib) = .{},
34
...@@ -6,7 +7,7 @@ pub fn deinit(scr: *LdScript, allocator: Allocator) void {...@@ -6,7 +7,7 @@ pub fn deinit(scr: *LdScript, allocator: Allocator) void {
6}7}
78
8pub const Error = error{9pub const Error = error{
9 InvalidScript,10 InvalidLdScript,
10 UnexpectedToken,11 UnexpectedToken,
11 UnknownCpuArch,12 UnknownCpuArch,
12 OutOfMemory,13 OutOfMemory,
...@@ -30,13 +31,12 @@ pub fn parse(scr: *LdScript, data: []const u8, elf_file: *Elf) Error!void {...@@ -30,13 +31,12 @@ pub fn parse(scr: *LdScript, data: []const u8, elf_file: *Elf) Error!void {
30 try line_col.append(.{ .line = line, .column = column });31 try line_col.append(.{ .line = line, .column = column });
31 switch (tok.id) {32 switch (tok.id) {
32 .invalid => {33 .invalid => {
33 // TODO errors34 try elf_file.reportParseError(scr.path, "invalid token in LD script: '{s}' ({d}:{d})", .{
34 // elf_file.base.fatal("invalid token in ld script: '{s}' ({d}:{d})", .{35 tok.get(data),
35 // tok.get(data),36 line,
36 // line,37 column,
37 // column,38 });
38 // });39 return error.InvalidLdScript;
39 return error.InvalidScript;
40 },40 },
41 .new_line => {41 .new_line => {
42 line += 1;42 line += 1;
...@@ -55,17 +55,16 @@ pub fn parse(scr: *LdScript, data: []const u8, elf_file: *Elf) Error!void {...@@ -55,17 +55,16 @@ pub fn parse(scr: *LdScript, data: []const u8, elf_file: *Elf) Error!void {
55 .args = &args,55 .args = &args,
56 }) catch |err| switch (err) {56 }) catch |err| switch (err) {
57 error.UnexpectedToken => {57 error.UnexpectedToken => {
58 // const last_token_id = parser.it.pos - 1;58 const last_token_id = parser.it.pos - 1;
59 // const last_token = parser.it.get(last_token_id);59 const last_token = parser.it.get(last_token_id);
60 // const lcol = line_col.items[last_token_id];60 const lcol = line_col.items[last_token_id];
61 // TODO errors61 try elf_file.reportParseError(scr.path, "unexpected token in LD script: {s}: '{s}' ({d}:{d})", .{
62 // elf_file.base.fatal("unexpected token in ld script: {s} : '{s}' ({d}:{d})", .{62 @tagName(last_token.id),
63 // @tagName(last_token.id),63 last_token.get(data),
64 // last_token.get(data),64 lcol.line,
65 // lcol.line,65 lcol.column,
66 // lcol.column,66 });
67 // });67 return error.InvalidLdScript;
68 return error.InvalidScript;
69 },68 },
70 else => |e| return e,69 else => |e| return e,
71 };70 };
src/link/Elf/Object.zig+2-2
...@@ -75,7 +75,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {...@@ -75,7 +75,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
75 "corrupted header: section header table extends past the end of file",75 "corrupted header: section header table extends past the end of file",
76 .{},76 .{},
77 );77 );
78 return error.LinkFail;78 return error.MalformedObject;
79 }79 }
8080
81 const shoff = math.cast(usize, self.header.?.e_shoff) orelse return error.Overflow;81 const shoff = math.cast(usize, self.header.?.e_shoff) orelse return error.Overflow;
...@@ -88,7 +88,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {...@@ -88,7 +88,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
88 for (shdrs) |shdr| {88 for (shdrs) |shdr| {
89 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {89 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {
90 try elf_file.reportParseError2(self.index, "corrupted section header", .{});90 try elf_file.reportParseError2(self.index, "corrupted section header", .{});
91 return error.LinkFail;91 return error.MalformedObject;
92 }92 }
93 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));93 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));
94 }94 }
src/link/Elf/SharedObject.zig+2-2
...@@ -70,7 +70,7 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {...@@ -70,7 +70,7 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {
70 "corrupted header: section header table extends past the end of file",70 "corrupted header: section header table extends past the end of file",
71 .{},71 .{},
72 );72 );
73 return error.LinkFail;73 return error.MalformedObject;
74 }74 }
7575
76 const shoff = std.math.cast(usize, self.header.?.e_shoff) orelse return error.Overflow;76 const shoff = std.math.cast(usize, self.header.?.e_shoff) orelse return error.Overflow;
...@@ -84,7 +84,7 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {...@@ -84,7 +84,7 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {
84 for (shdrs, 0..) |shdr, i| {84 for (shdrs, 0..) |shdr, i| {
85 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {85 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {
86 try elf_file.reportParseError2(self.index, "corrupted section header", .{});86 try elf_file.reportParseError2(self.index, "corrupted section header", .{});
87 return error.LinkFail;87 return error.MalformedObject;
88 }88 }
89 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));89 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));
90 switch (shdr.sh_type) {90 switch (shdr.sh_type) {