authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-10-16 13:20:19+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-02 22:05:21-05:00
log0769afbb0f2fbb9c72d97ec0bcdcaba0ac916341
treefa23c874202671f84c7fcc5b7b751094c1e50170
parentc824b350511780581c0e5c1da85d0d9d769701ea

macho: refactors errors from parsing DWARF

Currently we don't report any errors to the user due to a bug in self-hosted x86_64-macos backend.

2 files changed, 18 insertions(+), 16 deletions(-)

src/link/MachO/Dwarf.zig+7-9
...@@ -29,8 +29,7 @@ pub const InfoReader = struct {...@@ -29,8 +29,7 @@ pub const InfoReader = struct {
29 return p.ctx.debug_info;29 return p.ctx.debug_info;
30 }30 }
3131
32 pub fn readCompileUnitHeader(p: *InfoReader, macho_file: *MachO) !CompileUnitHeader {32 pub fn readCompileUnitHeader(p: *InfoReader) !CompileUnitHeader {
33 _ = macho_file;
34 var length: u64 = try p.readInt(u32);33 var length: u64 = try p.readInt(u32);
35 const is_64bit = length == 0xffffffff;34 const is_64bit = length == 0xffffffff;
36 if (is_64bit) {35 if (is_64bit) {
...@@ -67,7 +66,7 @@ pub const InfoReader = struct {...@@ -67,7 +66,7 @@ pub const InfoReader = struct {
67 };66 };
68 }67 }
6968
70 pub fn seekToDie(p: *InfoReader, code: Code, cuh: CompileUnitHeader, abbrev_reader: *AbbrevReader, macho_file: *MachO) !void {69 pub fn seekToDie(p: *InfoReader, code: Code, cuh: CompileUnitHeader, abbrev_reader: *AbbrevReader) !void {
71 const cuh_length = math.cast(usize, cuh.length) orelse return error.Overflow;70 const cuh_length = math.cast(usize, cuh.length) orelse return error.Overflow;
72 const end_pos = p.pos + switch (cuh.format) {71 const end_pos = p.pos + switch (cuh.format) {
73 .dwarf32 => @as(usize, 4),72 .dwarf32 => @as(usize, 4),
...@@ -79,7 +78,7 @@ pub const InfoReader = struct {...@@ -79,7 +78,7 @@ pub const InfoReader = struct {
79 if (di_code == code) return;78 if (di_code == code) return;
8079
81 while (try abbrev_reader.readAttr()) |attr| {80 while (try abbrev_reader.readAttr()) |attr| {
82 try p.skip(attr.form, cuh, macho_file);81 try p.skip(attr.form, cuh);
83 }82 }
84 }83 }
85 return error.UnexpectedEndOfFile;84 return error.UnexpectedEndOfFile;
...@@ -87,8 +86,7 @@ pub const InfoReader = struct {...@@ -87,8 +86,7 @@ pub const InfoReader = struct {
8786
88 /// When skipping attributes, we don't really need to be able to handle them all87 /// When skipping attributes, we don't really need to be able to handle them all
89 /// since we only ever care about the DW_TAG_compile_unit.88 /// since we only ever care about the DW_TAG_compile_unit.
90 pub fn skip(p: *InfoReader, form: Form, cuh: CompileUnitHeader, macho_file: *MachO) !void {89 pub fn skip(p: *InfoReader, form: Form, cuh: CompileUnitHeader) !void {
91 _ = macho_file;
92 switch (form) {90 switch (form) {
93 dw.FORM.sec_offset,91 dw.FORM.sec_offset,
94 dw.FORM.ref_addr,92 dw.FORM.ref_addr,
...@@ -158,8 +156,8 @@ pub const InfoReader = struct {...@@ -158,8 +156,8 @@ pub const InfoReader = struct {
158 _ = try p.readIndex(form);156 _ = try p.readIndex(form);
159 },157 },
160158
161 else => return error.UnknownForm,159 else => return error.UnhandledForm,
162 } else return error.UnknownForm,160 } else return error.UnhandledForm,
163 }161 }
164 }162 }
165163
...@@ -195,7 +193,7 @@ pub const InfoReader = struct {...@@ -195,7 +193,7 @@ pub const InfoReader = struct {
195 return switch (form) {193 return switch (form) {
196 dw.FORM.strx1, dw.FORM.addrx1 => try p.readByte(),194 dw.FORM.strx1, dw.FORM.addrx1 => try p.readByte(),
197 dw.FORM.strx2, dw.FORM.addrx2 => try p.readInt(u16),195 dw.FORM.strx2, dw.FORM.addrx2 => try p.readInt(u16),
198 dw.FORM.strx3, dw.FORM.addrx3 => error.UnhandledDwForm,196 dw.FORM.strx3, dw.FORM.addrx3 => error.UnhandledForm,
199 dw.FORM.strx4, dw.FORM.addrx4 => try p.readInt(u32),197 dw.FORM.strx4, dw.FORM.addrx4 => try p.readInt(u32),
200 dw.FORM.strx, dw.FORM.addrx => try p.readUleb128(u64),198 dw.FORM.strx, dw.FORM.addrx => try p.readUleb128(u64),
201 else => return error.UnhandledIndexForm,199 else => return error.UnhandledIndexForm,
src/link/MachO/Object.zig+11-7
...@@ -1362,6 +1362,8 @@ fn parseDebugInfo(self: *Object, macho_file: *MachO) !void {...@@ -1362,6 +1362,8 @@ fn parseDebugInfo(self: *Object, macho_file: *MachO) !void {
1362 if (mem.eql(u8, sect.sectName(), "__debug_str")) {1362 if (mem.eql(u8, sect.sectName(), "__debug_str")) {
1363 dwarf.debug_str = try self.readSectionData(gpa, file, n_sect);1363 dwarf.debug_str = try self.readSectionData(gpa, file, n_sect);
1364 }1364 }
1365 // __debug_str_offs[ets] section is a new addition in DWARFv5 and is generally
1366 // required in order to correctly parse strings.
1365 if (mem.eql(u8, sect.sectName(), "__debug_str_offs")) {1367 if (mem.eql(u8, sect.sectName(), "__debug_str_offs")) {
1366 dwarf.debug_str_offsets = try self.readSectionData(gpa, file, n_sect);1368 dwarf.debug_str_offsets = try self.readSectionData(gpa, file, n_sect);
1367 }1369 }
...@@ -1369,20 +1371,22 @@ fn parseDebugInfo(self: *Object, macho_file: *MachO) !void {...@@ -1369,20 +1371,22 @@ fn parseDebugInfo(self: *Object, macho_file: *MachO) !void {
13691371
1370 if (dwarf.debug_info.len == 0) return;1372 if (dwarf.debug_info.len == 0) return;
13711373
1372 self.compile_unit = try self.findCompileUnit(gpa, dwarf, macho_file);1374 // TODO return error once we fix emitting DWARF in self-hosted backend.
1375 // https://github.com/ziglang/zig/issues/21719
1376 self.compile_unit = self.findCompileUnit(gpa, dwarf) catch null;
1373}1377}
13741378
1375fn findCompileUnit(self: *Object, gpa: Allocator, ctx: Dwarf, macho_file: *MachO) !CompileUnit {1379fn findCompileUnit(self: *Object, gpa: Allocator, ctx: Dwarf) !CompileUnit {
1376 var info_reader = Dwarf.InfoReader{ .ctx = ctx };1380 var info_reader = Dwarf.InfoReader{ .ctx = ctx };
1377 var abbrev_reader = Dwarf.AbbrevReader{ .ctx = ctx };1381 var abbrev_reader = Dwarf.AbbrevReader{ .ctx = ctx };
13781382
1379 const cuh = try info_reader.readCompileUnitHeader(macho_file);1383 const cuh = try info_reader.readCompileUnitHeader();
1380 try abbrev_reader.seekTo(cuh.debug_abbrev_offset);1384 try abbrev_reader.seekTo(cuh.debug_abbrev_offset);
13811385
1382 const cu_decl = (try abbrev_reader.readDecl()) orelse return error.UnexpectedEndOfFile;1386 const cu_decl = (try abbrev_reader.readDecl()) orelse return error.UnexpectedEndOfFile;
1383 if (cu_decl.tag != Dwarf.TAG.compile_unit) return error.UnexpectedTag;1387 if (cu_decl.tag != Dwarf.TAG.compile_unit) return error.UnexpectedTag;
13841388
1385 try info_reader.seekToDie(cu_decl.code, cuh, &abbrev_reader, macho_file);1389 try info_reader.seekToDie(cu_decl.code, cuh, &abbrev_reader);
13861390
1387 const Pos = struct {1391 const Pos = struct {
1388 pos: usize,1392 pos: usize,
...@@ -1405,10 +1409,10 @@ fn findCompileUnit(self: *Object, gpa: Allocator, ctx: Dwarf, macho_file: *MachO...@@ -1405,10 +1409,10 @@ fn findCompileUnit(self: *Object, gpa: Allocator, ctx: Dwarf, macho_file: *MachO
1405 Dwarf.AT.str_offsets_base => saved.str_offsets_base = pos,1409 Dwarf.AT.str_offsets_base => saved.str_offsets_base = pos,
1406 else => {},1410 else => {},
1407 }1411 }
1408 try info_reader.skip(attr.form, cuh, macho_file);1412 try info_reader.skip(attr.form, cuh);
1409 }1413 }
14101414
1411 if (saved.comp_dir == null) return error.MissingCompDir;1415 if (saved.comp_dir == null) return error.MissingCompileDir;
1412 if (saved.tu_name == null) return error.MissingTuName;1416 if (saved.tu_name == null) return error.MissingTuName;
14131417
1414 const str_offsets_base: ?u64 = if (saved.str_offsets_base) |str_offsets_base| str_offsets_base: {1418 const str_offsets_base: ?u64 = if (saved.str_offsets_base) |str_offsets_base| str_offsets_base: {
...@@ -1433,7 +1437,7 @@ fn findCompileUnit(self: *Object, gpa: Allocator, ctx: Dwarf, macho_file: *MachO...@@ -1433,7 +1437,7 @@ fn findCompileUnit(self: *Object, gpa: Allocator, ctx: Dwarf, macho_file: *MachO
1433 Dwarf.FORM.strx3,1437 Dwarf.FORM.strx3,
1434 Dwarf.FORM.strx4,1438 Dwarf.FORM.strx4,
1435 => blk: {1439 => blk: {
1436 const base = str_offsets_base orelse return error.MalformedDwarf;1440 const base = str_offsets_base orelse return error.MissingStrOffsetsBase;
1437 break :blk try self.addString(gpa, try info_reader.readStringIndexed(pos.form, cuh, base));1441 break :blk try self.addString(gpa, try info_reader.readStringIndexed(pos.form, cuh, base));
1438 },1442 },
1439 else => return error.InvalidForm,1443 else => return error.InvalidForm,