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
10421042
10431043 for (positionals.items) |obj| {
10441044 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1045 error.LinkFail, error.InvalidCpuArch => {}, // already reported
1045 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
10461046 else => |e| try self.reportParseError(
10471047 obj.path,
10481048 "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
11281128
11291129 for (system_libs.items) |lib| {
11301130 self.parseLibrary(lib, false) catch |err| switch (err) {
1131 error.LinkFail, error.InvalidCpuArch => {}, // already reported
1131 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
11321132 else => |e| try self.reportParseError(
11331133 lib.path,
11341134 "unexpected error: parsing library failed with error {s}",
......@@ -1151,7 +1151,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11511151
11521152 for (positionals.items) |obj| {
11531153 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1154 error.LinkFail, error.InvalidCpuArch => {}, // already reported
1154 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
11551155 else => |e| try self.reportParseError(
11561156 obj.path,
11571157 "unexpected error: parsing input file failed with error {s}",
......@@ -1316,7 +1316,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const
13161316
13171317 for (positionals.items) |obj| {
13181318 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1319 error.LinkFail, error.InvalidCpuArch => {}, // already reported
1319 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
13201320 else => |e| try self.reportParseError(
13211321 obj.path,
13221322 "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)
14531453
14541454 for (positionals.items) |obj| {
14551455 self.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
1456 error.LinkFail, error.InvalidCpuArch => {}, // already reported
1456 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
14571457 else => |e| try self.reportParseError(
14581458 obj.path,
14591459 "unexpected error: parsing input file failed with error {s}",
......@@ -1785,8 +1785,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
17851785}
17861786
17871787const ParseError = error{
1788 LinkFail,
1789 UnknownFileType,
1788 MalformedObject,
1789 MalformedArchive,
17901790 InvalidCpuArch,
17911791 OutOfMemory,
17921792 Overflow,
......@@ -1816,11 +1816,7 @@ fn parseLibrary(self: *Elf, lib: SystemLib, must_link: bool) ParseError!void {
18161816 } else if (try SharedObject.isSharedObject(lib.path)) {
18171817 try self.parseSharedObject(lib);
18181818 } else {
1819 // TODO if the script has a top-level comment identifying it as GNU ld script,
1820 // then report parse errors. Otherwise return UnknownFileType.
1821 self.parseLdScript(lib) catch |err| switch (err) {
1822 else => return error.UnknownFileType,
1823 };
1819 try self.parseLdScript(lib);
18241820 }
18251821}
18261822
......@@ -1902,7 +1898,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
19021898 const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));
19031899 defer gpa.free(data);
19041900
1905 var script = LdScript{};
1901 var script = LdScript{ .path = lib.path };
19061902 defer script.deinit(gpa);
19071903 try script.parse(data, self);
19081904
......@@ -1963,7 +1959,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
19631959 .needed = scr_obj.needed,
19641960 .path = full_path,
19651961 }, false) catch |err| switch (err) {
1966 error.LinkFail, error.InvalidCpuArch => {}, // already reported
1962 error.MalformedObject, error.InvalidCpuArch => {}, // already reported
19671963 else => |e| try self.reportParseError(
19681964 full_path,
19691965 "unexpected error: parsing library failed with error {s}",
......@@ -2195,7 +2191,7 @@ fn scanRelocs(self: *Elf) !void {
21952191 try object.scanRelocs(self, &undefs);
21962192 }
21972193
2198 try self.reportUndefined(&undefs);
2194 try self.reportUndefinedSymbols(&undefs);
21992195
22002196 for (self.symbols.items, 0..) |*sym, i| {
22012197 const index = @as(u32, @intCast(i));
......@@ -4760,7 +4756,7 @@ fn writeAtoms(self: *Elf) !void {
47604756 try self.base.file.?.pwriteAll(buffer, sh_offset);
47614757 }
47624758
4763 try self.reportUndefined(&undefs);
4759 try self.reportUndefinedSymbols(&undefs);
47644760}
47654761
47664762fn writeAtomsObject(self: *Elf) !void {
......@@ -6023,7 +6019,7 @@ pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 {
60236019 return off;
60246020}
60256021
6026fn reportUndefined(self: *Elf, undefs: anytype) !void {
6022fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
60276023 const gpa = self.base.allocator;
60286024 const max_notes = 4;
60296025
......@@ -6065,7 +6061,7 @@ fn reportMissingLibraryError(
60656061 }
60666062}
60676063
6068fn reportParseError(
6064pub fn reportParseError(
60696065 self: *Elf,
60706066 path: []const u8,
60716067 comptime format: []const u8,
src/link/Elf/LdScript.zig+18-19
......@@ -1,3 +1,4 @@
1path: []const u8,
12cpu_arch: ?std.Target.Cpu.Arch = null,
23args: std.ArrayListUnmanaged(Elf.SystemLib) = .{},
34
......@@ -6,7 +7,7 @@ pub fn deinit(scr: *LdScript, allocator: Allocator) void {
67}
78
89pub const Error = error{
9 InvalidScript,
10 InvalidLdScript,
1011 UnexpectedToken,
1112 UnknownCpuArch,
1213 OutOfMemory,
......@@ -30,13 +31,12 @@ pub fn parse(scr: *LdScript, data: []const u8, elf_file: *Elf) Error!void {
3031 try line_col.append(.{ .line = line, .column = column });
3132 switch (tok.id) {
3233 .invalid => {
33 // TODO errors
34 // elf_file.base.fatal("invalid token in ld script: '{s}' ({d}:{d})", .{
35 // tok.get(data),
36 // line,
37 // column,
38 // });
39 return error.InvalidScript;
34 try elf_file.reportParseError(scr.path, "invalid token in LD script: '{s}' ({d}:{d})", .{
35 tok.get(data),
36 line,
37 column,
38 });
39 return error.InvalidLdScript;
4040 },
4141 .new_line => {
4242 line += 1;
......@@ -55,17 +55,16 @@ pub fn parse(scr: *LdScript, data: []const u8, elf_file: *Elf) Error!void {
5555 .args = &args,
5656 }) catch |err| switch (err) {
5757 error.UnexpectedToken => {
58 // const last_token_id = parser.it.pos - 1;
59 // const last_token = parser.it.get(last_token_id);
60 // const lcol = line_col.items[last_token_id];
61 // TODO errors
62 // elf_file.base.fatal("unexpected token in ld script: {s} : '{s}' ({d}:{d})", .{
63 // @tagName(last_token.id),
64 // last_token.get(data),
65 // lcol.line,
66 // lcol.column,
67 // });
68 return error.InvalidScript;
58 const last_token_id = parser.it.pos - 1;
59 const last_token = parser.it.get(last_token_id);
60 const lcol = line_col.items[last_token_id];
61 try elf_file.reportParseError(scr.path, "unexpected token in LD script: {s}: '{s}' ({d}:{d})", .{
62 @tagName(last_token.id),
63 last_token.get(data),
64 lcol.line,
65 lcol.column,
66 });
67 return error.InvalidLdScript;
6968 },
7069 else => |e| return e,
7170 };
src/link/Elf/Object.zig+2-2
......@@ -75,7 +75,7 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
7575 "corrupted header: section header table extends past the end of file",
7676 .{},
7777 );
78 return error.LinkFail;
78 return error.MalformedObject;
7979 }
8080
8181 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 {
8888 for (shdrs) |shdr| {
8989 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {
9090 try elf_file.reportParseError2(self.index, "corrupted section header", .{});
91 return error.LinkFail;
91 return error.MalformedObject;
9292 }
9393 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));
9494 }
src/link/Elf/SharedObject.zig+2-2
......@@ -70,7 +70,7 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {
7070 "corrupted header: section header table extends past the end of file",
7171 .{},
7272 );
73 return error.LinkFail;
73 return error.MalformedObject;
7474 }
7575
7676 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 {
8484 for (shdrs, 0..) |shdr, i| {
8585 if (self.data.len < shdr.sh_offset or self.data.len < shdr.sh_offset + shdr.sh_size) {
8686 try elf_file.reportParseError2(self.index, "corrupted section header", .{});
87 return error.LinkFail;
87 return error.MalformedObject;
8888 }
8989 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));
9090 switch (shdr.sh_type) {