authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-30 22:29:24+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-30 22:29:27+02:00
loga7240f0c99426a546b05f7e8bb086805a2766ea9
treee0fcdde6783e607fb42bd1399f60f2bd89845be6
parentebe371b75769dcc5526cdb7650c875764fb536e4

macho: remove error.UnhandledDwFormValue from link.File

Eventually, we will validate DWARF info upfront and report errors to the user but this will require a rewrite of several parts of the linker so leaving as a TODO for the near future.

3 files changed, 24 insertions(+), 12 deletions(-)

src/link.zig-1
...@@ -751,7 +751,6 @@ pub const File = struct {...@@ -751,7 +751,6 @@ pub const File = struct {
751 UnexpectedRemainder,751 UnexpectedRemainder,
752 UnexpectedTable,752 UnexpectedTable,
753 UnexpectedValue,753 UnexpectedValue,
754 UnhandledDwFormValue,
755 UnknownFeature,754 UnknownFeature,
756 Unseekable,755 Unseekable,
757 UnsupportedCpuArchitecture,756 UnsupportedCpuArchitecture,
src/link/MachO.zig+22-10
...@@ -4101,6 +4101,9 @@ fn writeSymtab(self: *MachO) !SymtabCtx {...@@ -4101,6 +4101,9 @@ fn writeSymtab(self: *MachO) !SymtabCtx {
4101 };4101 };
4102}4102}
41034103
4104// TODO this function currently skips generating symbol stabs in case errors are encountered in DWARF data.
4105// I think we should actually report those errors to the user and let them decide if they want to strip debug info
4106// in that case or not.
4104fn generateSymbolStabs(4107fn generateSymbolStabs(
4105 self: *MachO,4108 self: *MachO,
4106 object: Object,4109 object: Object,
...@@ -4127,10 +4130,14 @@ fn generateSymbolStabs(...@@ -4127,10 +4130,14 @@ fn generateSymbolStabs(
4127 };4130 };
41284131
4129 var abbrev_it = compile_unit.getAbbrevEntryIterator(debug_info);4132 var abbrev_it = compile_unit.getAbbrevEntryIterator(debug_info);
4130 const cu_entry: DwarfInfo.AbbrevEntry = while (try abbrev_it.next(lookup)) |entry| switch (entry.tag) {4133 const maybe_cu_entry: ?DwarfInfo.AbbrevEntry = blk: {
4131 dwarf.TAG.compile_unit => break entry,4134 while (abbrev_it.next(lookup) catch break :blk null) |entry| switch (entry.tag) {
4132 else => continue,4135 dwarf.TAG.compile_unit => break :blk entry,
4133 } else {4136 else => continue,
4137 } else break :blk null;
4138 };
4139
4140 const cu_entry = maybe_cu_entry orelse {
4134 log.debug("missing DWARF_TAG_compile_unit tag in {s}; skipping", .{object.name});4141 log.debug("missing DWARF_TAG_compile_unit tag in {s}; skipping", .{object.name});
4135 return;4142 return;
4136 };4143 };
...@@ -4139,11 +4146,13 @@ fn generateSymbolStabs(...@@ -4139,11 +4146,13 @@ fn generateSymbolStabs(
4139 var maybe_tu_comp_dir: ?[]const u8 = null;4146 var maybe_tu_comp_dir: ?[]const u8 = null;
4140 var attr_it = cu_entry.getAttributeIterator(debug_info, compile_unit.cuh);4147 var attr_it = cu_entry.getAttributeIterator(debug_info, compile_unit.cuh);
41414148
4142 while (try attr_it.next()) |attr| switch (attr.name) {4149 blk: {
4143 dwarf.AT.comp_dir => maybe_tu_comp_dir = attr.getString(debug_info, compile_unit.cuh) orelse continue,4150 while (attr_it.next() catch break :blk) |attr| switch (attr.name) {
4144 dwarf.AT.name => maybe_tu_name = attr.getString(debug_info, compile_unit.cuh) orelse continue,4151 dwarf.AT.comp_dir => maybe_tu_comp_dir = attr.getString(debug_info, compile_unit.cuh) orelse continue,
4145 else => continue,4152 dwarf.AT.name => maybe_tu_name = attr.getString(debug_info, compile_unit.cuh) orelse continue,
4146 };4153 else => continue,
4154 };
4155 }
41474156
4148 if (maybe_tu_name == null or maybe_tu_comp_dir == null) {4157 if (maybe_tu_name == null or maybe_tu_comp_dir == null) {
4149 log.debug("missing DWARF_AT_comp_dir and DWARF_AT_name attributes {s}; skipping", .{object.name});4158 log.debug("missing DWARF_AT_comp_dir and DWARF_AT_name attributes {s}; skipping", .{object.name});
...@@ -4183,7 +4192,10 @@ fn generateSymbolStabs(...@@ -4183,7 +4192,10 @@ fn generateSymbolStabs(
4183 var name_lookup = DwarfInfo.SubprogramLookupByName.init(gpa);4192 var name_lookup = DwarfInfo.SubprogramLookupByName.init(gpa);
4184 errdefer name_lookup.deinit();4193 errdefer name_lookup.deinit();
4185 try name_lookup.ensureUnusedCapacity(@as(u32, @intCast(object.atoms.items.len)));4194 try name_lookup.ensureUnusedCapacity(@as(u32, @intCast(object.atoms.items.len)));
4186 try debug_info.genSubprogramLookupByName(compile_unit, lookup, &name_lookup);4195 debug_info.genSubprogramLookupByName(compile_unit, lookup, &name_lookup) catch |err| switch (err) {
4196 error.UnhandledDwFormValue => {}, // TODO I don't like the fact we constantly re-iterate and hit this; we should validate once a priori
4197 else => |e| return e,
4198 };
4187 break :blk name_lookup;4199 break :blk name_lookup;
4188 } else null;4200 } else null;
4189 defer if (name_lookup) |*nl| nl.deinit();4201 defer if (name_lookup) |*nl| nl.deinit();
src/link/MachO/DwarfInfo.zig+2-1
...@@ -444,7 +444,8 @@ fn findFormSize(self: DwarfInfo, form: u64, di_off: usize, cuh: CompileUnit.Head...@@ -444,7 +444,8 @@ fn findFormSize(self: DwarfInfo, form: u64, di_off: usize, cuh: CompileUnit.Head
444 },444 },
445445
446 else => {446 else => {
447 log.err("unhandled DW_FORM_* value with identifier {x}", .{form});447 // TODO figure out how to handle this
448 log.debug("unhandled DW_FORM_* value with identifier {x}", .{form});
448 return error.UnhandledDwFormValue;449 return error.UnhandledDwFormValue;
449 },450 },
450 }451 }