authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-06 09:44:07+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-06 19:58:51+02:00
loge05de31a5fa8105b09eed37c9d023501b1289cd1
tree6e3d3b90970f46705d62c527dd9be0d28dece1fd
parent0cab01adbf8ba495f214f948d34a3e6bd133bbc4

dwarf: fix incorrect type reloc for unions

Split type relocs into two kinds: local and global. Global relocs use a global type resolver and calculate offset to the existing definition of a type abbreviation. Local relocs use offset in the abbrev section of the containing atom plus addend to generate a local relocation.

6 files changed, 69 insertions(+), 56 deletions(-)

src/arch/arm/CodeGen.zig+1-1
...@@ -3187,7 +3187,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) error{OutOfMemory}!void {...@@ -3187,7 +3187,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) error{OutOfMemory}!void {
3187 .macho => unreachable,3187 .macho => unreachable,
3188 else => unreachable,3188 else => unreachable,
3189 };3189 };
3190 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);3190 try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
3191 },3191 },
3192 .plan9 => {},3192 .plan9 => {},
3193 .none => {},3193 .none => {},
src/arch/riscv64/CodeGen.zig+1-1
...@@ -754,7 +754,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -754,7 +754,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
754 .macho => unreachable,754 .macho => unreachable,
755 else => unreachable,755 else => unreachable,
756 };756 };
757 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);757 try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
758 },758 },
759 .plan9 => {},759 .plan9 => {},
760 .none => {},760 .none => {},
src/arch/sparc64/CodeGen.zig+1-1
...@@ -1550,7 +1550,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -1550,7 +1550,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
1550 .elf => &mod.declPtr(self.mod_fn.owner_decl).link.elf.dbg_info_atom,1550 .elf => &mod.declPtr(self.mod_fn.owner_decl).link.elf.dbg_info_atom,
1551 else => unreachable,1551 else => unreachable,
1552 };1552 };
1553 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);1553 try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
1554 },1554 },
1555 else => {},1555 else => {},
1556 }1556 }
src/arch/wasm/CodeGen.zig+1-1
...@@ -1050,7 +1050,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -1050,7 +1050,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
1050 const index = dbg_info.items.len;1050 const index = dbg_info.items.len;
1051 try dbg_info.resize(index + 4);1051 try dbg_info.resize(index + 4);
1052 const atom = &self.decl.link.wasm.dbg_info_atom;1052 const atom = &self.decl.link.wasm.dbg_info_atom;
1053 try dwarf.addTypeReloc(atom, ty, @intCast(u32, index), null);1053 try dwarf.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
1054 },1054 },
1055 .plan9 => unreachable,1055 .plan9 => unreachable,
1056 .none => {},1056 .none => {},
src/arch/x86_64/CodeGen.zig+1-1
...@@ -4371,7 +4371,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -4371,7 +4371,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
4371 .macho => &fn_owner_decl.link.macho.dbg_info_atom,4371 .macho => &fn_owner_decl.link.macho.dbg_info_atom,
4372 else => unreachable,4372 else => unreachable,
4373 };4373 };
4374 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);4374 try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
4375 },4375 },
4376 .plan9 => {},4376 .plan9 => {},
4377 .none => {},4377 .none => {},
src/link/Dwarf.zig+64-51
...@@ -110,13 +110,22 @@ pub const DeclState = struct {...@@ -110,13 +110,22 @@ pub const DeclState = struct {
110 });110 });
111 }111 }
112112
113 pub fn addTypeReloc(113 /// Adds local type relocation of the form: @offset => @this + addend
114 self: *DeclState,114 /// @this signifies the offset within the .debug_abbrev section of the containing atom.
115 atom: *const Atom,115 pub fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
116 ty: Type,116 log.debug("{x}: @this + {x}", .{ offset, addend });
117 offset: u32,117 try self.abbrev_relocs.append(self.gpa, .{
118 addend: ?u32,118 .target = null,
119 ) !void {119 .atom = atom,
120 .offset = offset,
121 .addend = addend,
122 });
123 }
124
125 /// Adds global type relocation of the form: @offset => @symbol + 0
126 /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
127 /// which we use as our target of the relocation.
128 pub fn addTypeRelocGlobal(self: *DeclState, atom: *const Atom, ty: Type, offset: u32) !void {
120 const resolv = self.abbrev_resolver.getContext(ty, .{129 const resolv = self.abbrev_resolver.getContext(ty, .{
121 .mod = self.mod,130 .mod = self.mod,
122 }) orelse blk: {131 }) orelse blk: {
...@@ -134,14 +143,12 @@ pub const DeclState = struct {...@@ -134,14 +143,12 @@ pub const DeclState = struct {
134 .mod = self.mod,143 .mod = self.mod,
135 }).?;144 }).?;
136 };145 };
137 const add: u32 = addend orelse 0;146 log.debug("{x}: @{d} + 0", .{ offset, resolv });
138
139 log.debug("{x}: @{d} + {x}", .{ offset, resolv, add });
140 try self.abbrev_relocs.append(self.gpa, .{147 try self.abbrev_relocs.append(self.gpa, .{
141 .target = resolv,148 .target = resolv,
142 .atom = atom,149 .atom = atom,
143 .offset = offset,150 .offset = offset,
144 .addend = add,151 .addend = 0,
145 });152 });
146 }153 }
147154
...@@ -213,7 +220,7 @@ pub const DeclState = struct {...@@ -213,7 +220,7 @@ pub const DeclState = struct {
213 // DW.AT.type, DW.FORM.ref4220 // DW.AT.type, DW.FORM.ref4
214 var index = dbg_info_buffer.items.len;221 var index = dbg_info_buffer.items.len;
215 try dbg_info_buffer.resize(index + 4);222 try dbg_info_buffer.resize(index + 4);
216 try self.addTypeReloc(atom, Type.bool, @intCast(u32, index), null);223 try self.addTypeRelocGlobal(atom, Type.bool, @intCast(u32, index));
217 // DW.AT.data_member_location, DW.FORM.sdata224 // DW.AT.data_member_location, DW.FORM.sdata
218 try dbg_info_buffer.ensureUnusedCapacity(6);225 try dbg_info_buffer.ensureUnusedCapacity(6);
219 dbg_info_buffer.appendAssumeCapacity(0);226 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -225,7 +232,7 @@ pub const DeclState = struct {...@@ -225,7 +232,7 @@ pub const DeclState = struct {
225 // DW.AT.type, DW.FORM.ref4232 // DW.AT.type, DW.FORM.ref4
226 index = dbg_info_buffer.items.len;233 index = dbg_info_buffer.items.len;
227 try dbg_info_buffer.resize(index + 4);234 try dbg_info_buffer.resize(index + 4);
228 try self.addTypeReloc(atom, payload_ty, @intCast(u32, index), null);235 try self.addTypeRelocGlobal(atom, payload_ty, @intCast(u32, index));
229 // DW.AT.data_member_location, DW.FORM.sdata236 // DW.AT.data_member_location, DW.FORM.sdata
230 const offset = abi_size - payload_ty.abiSize(target);237 const offset = abi_size - payload_ty.abiSize(target);
231 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);238 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
...@@ -254,7 +261,7 @@ pub const DeclState = struct {...@@ -254,7 +261,7 @@ pub const DeclState = struct {
254 try dbg_info_buffer.resize(index + 4);261 try dbg_info_buffer.resize(index + 4);
255 var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);262 var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);
256 const ptr_ty = ty.slicePtrFieldType(buf);263 const ptr_ty = ty.slicePtrFieldType(buf);
257 try self.addTypeReloc(atom, ptr_ty, @intCast(u32, index), null);264 try self.addTypeRelocGlobal(atom, ptr_ty, @intCast(u32, index));
258 // DW.AT.data_member_location, DW.FORM.sdata265 // DW.AT.data_member_location, DW.FORM.sdata
259 try dbg_info_buffer.ensureUnusedCapacity(6);266 try dbg_info_buffer.ensureUnusedCapacity(6);
260 dbg_info_buffer.appendAssumeCapacity(0);267 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -266,7 +273,7 @@ pub const DeclState = struct {...@@ -266,7 +273,7 @@ pub const DeclState = struct {
266 // DW.AT.type, DW.FORM.ref4273 // DW.AT.type, DW.FORM.ref4
267 index = dbg_info_buffer.items.len;274 index = dbg_info_buffer.items.len;
268 try dbg_info_buffer.resize(index + 4);275 try dbg_info_buffer.resize(index + 4);
269 try self.addTypeReloc(atom, Type.usize, @intCast(u32, index), null);276 try self.addTypeRelocGlobal(atom, Type.usize, @intCast(u32, index));
270 // DW.AT.data_member_location, DW.FORM.sdata277 // DW.AT.data_member_location, DW.FORM.sdata
271 try dbg_info_buffer.ensureUnusedCapacity(2);278 try dbg_info_buffer.ensureUnusedCapacity(2);
272 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize));279 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize));
...@@ -278,7 +285,7 @@ pub const DeclState = struct {...@@ -278,7 +285,7 @@ pub const DeclState = struct {
278 // DW.AT.type, DW.FORM.ref4285 // DW.AT.type, DW.FORM.ref4
279 const index = dbg_info_buffer.items.len;286 const index = dbg_info_buffer.items.len;
280 try dbg_info_buffer.resize(index + 4);287 try dbg_info_buffer.resize(index + 4);
281 try self.addTypeReloc(atom, ty.childType(), @intCast(u32, index), null);288 try self.addTypeRelocGlobal(atom, ty.childType(), @intCast(u32, index));
282 }289 }
283 },290 },
284 .Array => {291 .Array => {
...@@ -289,13 +296,13 @@ pub const DeclState = struct {...@@ -289,13 +296,13 @@ pub const DeclState = struct {
289 // DW.AT.type, DW.FORM.ref4296 // DW.AT.type, DW.FORM.ref4
290 var index = dbg_info_buffer.items.len;297 var index = dbg_info_buffer.items.len;
291 try dbg_info_buffer.resize(index + 4);298 try dbg_info_buffer.resize(index + 4);
292 try self.addTypeReloc(atom, ty.childType(), @intCast(u32, index), null);299 try self.addTypeRelocGlobal(atom, ty.childType(), @intCast(u32, index));
293 // DW.AT.subrange_type300 // DW.AT.subrange_type
294 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_dim));301 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_dim));
295 // DW.AT.type, DW.FORM.ref4302 // DW.AT.type, DW.FORM.ref4
296 index = dbg_info_buffer.items.len;303 index = dbg_info_buffer.items.len;
297 try dbg_info_buffer.resize(index + 4);304 try dbg_info_buffer.resize(index + 4);
298 try self.addTypeReloc(atom, Type.usize, @intCast(u32, index), null);305 try self.addTypeRelocGlobal(atom, Type.usize, @intCast(u32, index));
299 // DW.AT.count, DW.FORM.udata306 // DW.AT.count, DW.FORM.udata
300 const len = ty.arrayLenIncludingSentinel();307 const len = ty.arrayLenIncludingSentinel();
301 try leb128.writeULEB128(dbg_info_buffer.writer(), len);308 try leb128.writeULEB128(dbg_info_buffer.writer(), len);
...@@ -323,7 +330,7 @@ pub const DeclState = struct {...@@ -323,7 +330,7 @@ pub const DeclState = struct {
323 // DW.AT.type, DW.FORM.ref4330 // DW.AT.type, DW.FORM.ref4
324 var index = dbg_info_buffer.items.len;331 var index = dbg_info_buffer.items.len;
325 try dbg_info_buffer.resize(index + 4);332 try dbg_info_buffer.resize(index + 4);
326 try self.addTypeReloc(atom, field, @intCast(u32, index), null);333 try self.addTypeRelocGlobal(atom, field, @intCast(u32, index));
327 // DW.AT.data_member_location, DW.FORM.sdata334 // DW.AT.data_member_location, DW.FORM.sdata
328 const field_off = ty.structFieldOffset(field_index, target);335 const field_off = ty.structFieldOffset(field_index, target);
329 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);336 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
...@@ -354,7 +361,7 @@ pub const DeclState = struct {...@@ -354,7 +361,7 @@ pub const DeclState = struct {
354 // DW.AT.type, DW.FORM.ref4361 // DW.AT.type, DW.FORM.ref4
355 var index = dbg_info_buffer.items.len;362 var index = dbg_info_buffer.items.len;
356 try dbg_info_buffer.resize(index + 4);363 try dbg_info_buffer.resize(index + 4);
357 try self.addTypeReloc(atom, field.ty, @intCast(u32, index), null);364 try self.addTypeRelocGlobal(atom, field.ty, @intCast(u32, index));
358 // DW.AT.data_member_location, DW.FORM.sdata365 // DW.AT.data_member_location, DW.FORM.sdata
359 const field_off = ty.structFieldOffset(field_index, target);366 const field_off = ty.structFieldOffset(field_index, target);
360 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);367 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
...@@ -434,7 +441,7 @@ pub const DeclState = struct {...@@ -434,7 +441,7 @@ pub const DeclState = struct {
434 // DW.AT.type, DW.FORM.ref4441 // DW.AT.type, DW.FORM.ref4
435 const inner_union_index = dbg_info_buffer.items.len;442 const inner_union_index = dbg_info_buffer.items.len;
436 try dbg_info_buffer.resize(inner_union_index + 4);443 try dbg_info_buffer.resize(inner_union_index + 4);
437 try self.addTypeReloc(atom, ty, @intCast(u32, inner_union_index), 5);444 try self.addTypeRelocLocal(atom, @intCast(u32, inner_union_index), 5);
438 // DW.AT.data_member_location, DW.FORM.sdata445 // DW.AT.data_member_location, DW.FORM.sdata
439 try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset);446 try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset);
440 }447 }
...@@ -461,7 +468,7 @@ pub const DeclState = struct {...@@ -461,7 +468,7 @@ pub const DeclState = struct {
461 // DW.AT.type, DW.FORM.ref4468 // DW.AT.type, DW.FORM.ref4
462 const index = dbg_info_buffer.items.len;469 const index = dbg_info_buffer.items.len;
463 try dbg_info_buffer.resize(index + 4);470 try dbg_info_buffer.resize(index + 4);
464 try self.addTypeReloc(atom, field.ty, @intCast(u32, index), null);471 try self.addTypeRelocGlobal(atom, field.ty, @intCast(u32, index));
465 // DW.AT.data_member_location, DW.FORM.sdata472 // DW.AT.data_member_location, DW.FORM.sdata
466 try dbg_info_buffer.append(0);473 try dbg_info_buffer.append(0);
467 }474 }
...@@ -478,7 +485,7 @@ pub const DeclState = struct {...@@ -478,7 +485,7 @@ pub const DeclState = struct {
478 // DW.AT.type, DW.FORM.ref4485 // DW.AT.type, DW.FORM.ref4
479 const index = dbg_info_buffer.items.len;486 const index = dbg_info_buffer.items.len;
480 try dbg_info_buffer.resize(index + 4);487 try dbg_info_buffer.resize(index + 4);
481 try self.addTypeReloc(atom, union_obj.tag_ty, @intCast(u32, index), null);488 try self.addTypeRelocGlobal(atom, union_obj.tag_ty, @intCast(u32, index));
482 // DW.AT.data_member_location, DW.FORM.sdata489 // DW.AT.data_member_location, DW.FORM.sdata
483 try leb128.writeULEB128(dbg_info_buffer.writer(), tag_offset);490 try leb128.writeULEB128(dbg_info_buffer.writer(), tag_offset);
484491
...@@ -521,7 +528,7 @@ pub const DeclState = struct {...@@ -521,7 +528,7 @@ pub const DeclState = struct {
521 // DW.AT.type, DW.FORM.ref4528 // DW.AT.type, DW.FORM.ref4
522 var index = dbg_info_buffer.items.len;529 var index = dbg_info_buffer.items.len;
523 try dbg_info_buffer.resize(index + 4);530 try dbg_info_buffer.resize(index + 4);
524 try self.addTypeReloc(atom, payload_ty, @intCast(u32, index), null);531 try self.addTypeRelocGlobal(atom, payload_ty, @intCast(u32, index));
525 // DW.AT.data_member_location, DW.FORM.sdata532 // DW.AT.data_member_location, DW.FORM.sdata
526 try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off);533 try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off);
527534
...@@ -534,7 +541,7 @@ pub const DeclState = struct {...@@ -534,7 +541,7 @@ pub const DeclState = struct {
534 // DW.AT.type, DW.FORM.ref4541 // DW.AT.type, DW.FORM.ref4
535 index = dbg_info_buffer.items.len;542 index = dbg_info_buffer.items.len;
536 try dbg_info_buffer.resize(index + 4);543 try dbg_info_buffer.resize(index + 4);
537 try self.addTypeReloc(atom, error_ty, @intCast(u32, index), null);544 try self.addTypeRelocGlobal(atom, error_ty, @intCast(u32, index));
538 // DW.AT.data_member_location, DW.FORM.sdata545 // DW.AT.data_member_location, DW.FORM.sdata
539 try leb128.writeULEB128(dbg_info_buffer.writer(), error_off);546 try leb128.writeULEB128(dbg_info_buffer.writer(), error_off);
540547
...@@ -556,7 +563,9 @@ pub const AbbrevEntry = struct {...@@ -556,7 +563,9 @@ pub const AbbrevEntry = struct {
556};563};
557564
558pub const AbbrevRelocation = struct {565pub const AbbrevRelocation = struct {
559 target: u32,566 /// If target is null, we deal with a local relocation that is based on simple offset + addend
567 /// only.
568 target: ?u32,
560 atom: *const Atom,569 atom: *const Atom,
561 offset: u32,570 offset: u32,
562 addend: u32,571 addend: u32,
...@@ -740,12 +749,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl: *Module.Decl) !DeclState...@@ -740,12 +749,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl: *Module.Decl) !DeclState
740 .wasm => &decl.link.wasm.dbg_info_atom,749 .wasm => &decl.link.wasm.dbg_info_atom,
741 else => unreachable,750 else => unreachable,
742 };751 };
743 try decl_state.addTypeReloc(752 try decl_state.addTypeRelocGlobal(atom, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len));
744 atom,
745 fn_ret_type,
746 @intCast(u32, dbg_info_buffer.items.len),
747 null,
748 );
749 dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4753 dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4
750 }754 }
751755
...@@ -1036,30 +1040,39 @@ pub fn commitDeclState(...@@ -1036,30 +1040,39 @@ pub fn commitDeclState(
1036 try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));1040 try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));
10371041
1038 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {1042 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
1039 const symbol = decl_state.abbrev_table.items[reloc.target];1043 if (reloc.target) |target| {
1040 const ty = symbol.@"type";1044 const symbol = decl_state.abbrev_table.items[target];
1041 const deferred: bool = blk: {1045 const ty = symbol.@"type";
1042 if (ty.isAnyError()) break :blk true;1046 const deferred: bool = blk: {
1043 switch (ty.tag()) {1047 if (ty.isAnyError()) break :blk true;
1044 .error_set_inferred => {1048 switch (ty.tag()) {
1045 if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;1049 .error_set_inferred => {
1046 },1050 if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;
1047 else => {},1051 },
1052 else => {},
1053 }
1054 break :blk false;
1055 };
1056 if (deferred) {
1057 try self.global_abbrev_relocs.append(gpa, .{
1058 .target = null,
1059 .offset = reloc.offset,
1060 .atom = reloc.atom,
1061 .addend = reloc.addend,
1062 });
1063 } else {
1064 mem.writeInt(
1065 u32,
1066 dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)],
1067 symbol.atom.off + symbol.offset + reloc.addend,
1068 target_endian,
1069 );
1048 }1070 }
1049 break :blk false;
1050 };
1051 if (deferred) {
1052 try self.global_abbrev_relocs.append(gpa, .{
1053 .target = undefined,
1054 .offset = reloc.offset,
1055 .atom = reloc.atom,
1056 .addend = reloc.addend,
1057 });
1058 } else {1071 } else {
1059 mem.writeInt(1072 mem.writeInt(
1060 u32,1073 u32,
1061 dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)],1074 dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)],
1062 symbol.atom.off + symbol.offset + reloc.addend,1075 reloc.atom.off + reloc.offset + reloc.addend,
1063 target_endian,1076 target_endian,
1064 );1077 );
1065 }1078 }