Skip to content

Commit f671942

Browse files
kubkonandrewrk
authored andcommitted
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.
1 parent 14d0f4e commit f671942

File tree

6 files changed

+69
-56
lines changed

6 files changed

+69
-56
lines changed

src/arch/arm/CodeGen.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3187,7 +3187,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) error{OutOfMemory}!void {
31873187
.macho => unreachable,
31883188
else => unreachable,
31893189
};
3190-
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
3190+
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
31913191
},
31923192
.plan9 => {},
31933193
.none => {},

src/arch/riscv64/CodeGen.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
754754
.macho => unreachable,
755755
else => unreachable,
756756
};
757-
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
757+
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
758758
},
759759
.plan9 => {},
760760
.none => {},

src/arch/sparc64/CodeGen.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
15501550
.elf => &mod.declPtr(self.mod_fn.owner_decl).link.elf.dbg_info_atom,
15511551
else => unreachable,
15521552
};
1553-
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
1553+
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
15541554
},
15551555
else => {},
15561556
}

src/arch/wasm/CodeGen.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
10501050
const index = dbg_info.items.len;
10511051
try dbg_info.resize(index + 4);
10521052
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));
10541054
},
10551055
.plan9 => unreachable,
10561056
.none => {},

src/arch/x86_64/CodeGen.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4371,7 +4371,7 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
43714371
.macho => &fn_owner_decl.link.macho.dbg_info_atom,
43724372
else => unreachable,
43734373
};
4374-
try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
4374+
try dw.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
43754375
},
43764376
.plan9 => {},
43774377
.none => {},

src/link/Dwarf.zig

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,22 @@ pub const DeclState = struct {
110110
});
111111
}
112112

113-
pub fn addTypeReloc(
114-
self: *DeclState,
115-
atom: *const Atom,
116-
ty: Type,
117-
offset: u32,
118-
addend: ?u32,
119-
) !void {
113+
/// Adds local type relocation of the form: @offset => @this + addend
114+
/// @this signifies the offset within the .debug_abbrev section of the containing atom.
115+
pub fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
116+
log.debug("{x}: @this + {x}", .{ offset, addend });
117+
try self.abbrev_relocs.append(self.gpa, .{
118+
.target = null,
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 {
120129
const resolv = self.abbrev_resolver.getContext(ty, .{
121130
.mod = self.mod,
122131
}) orelse blk: {
@@ -134,14 +143,12 @@ pub const DeclState = struct {
134143
.mod = self.mod,
135144
}).?;
136145
};
137-
const add: u32 = addend orelse 0;
138-
139-
log.debug("{x}: @{d} + {x}", .{ offset, resolv, add });
146+
log.debug("{x}: @{d} + 0", .{ offset, resolv });
140147
try self.abbrev_relocs.append(self.gpa, .{
141148
.target = resolv,
142149
.atom = atom,
143150
.offset = offset,
144-
.addend = add,
151+
.addend = 0,
145152
});
146153
}
147154

@@ -213,7 +220,7 @@ pub const DeclState = struct {
213220
// DW.AT.type, DW.FORM.ref4
214221
var index = dbg_info_buffer.items.len;
215222
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));
217224
// DW.AT.data_member_location, DW.FORM.sdata
218225
try dbg_info_buffer.ensureUnusedCapacity(6);
219226
dbg_info_buffer.appendAssumeCapacity(0);
@@ -225,7 +232,7 @@ pub const DeclState = struct {
225232
// DW.AT.type, DW.FORM.ref4
226233
index = dbg_info_buffer.items.len;
227234
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));
229236
// DW.AT.data_member_location, DW.FORM.sdata
230237
const offset = abi_size - payload_ty.abiSize(target);
231238
try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
@@ -254,7 +261,7 @@ pub const DeclState = struct {
254261
try dbg_info_buffer.resize(index + 4);
255262
var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);
256263
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));
258265
// DW.AT.data_member_location, DW.FORM.sdata
259266
try dbg_info_buffer.ensureUnusedCapacity(6);
260267
dbg_info_buffer.appendAssumeCapacity(0);
@@ -266,7 +273,7 @@ pub const DeclState = struct {
266273
// DW.AT.type, DW.FORM.ref4
267274
index = dbg_info_buffer.items.len;
268275
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));
270277
// DW.AT.data_member_location, DW.FORM.sdata
271278
try dbg_info_buffer.ensureUnusedCapacity(2);
272279
dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize));
@@ -278,7 +285,7 @@ pub const DeclState = struct {
278285
// DW.AT.type, DW.FORM.ref4
279286
const index = dbg_info_buffer.items.len;
280287
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));
282289
}
283290
},
284291
.Array => {
@@ -289,13 +296,13 @@ pub const DeclState = struct {
289296
// DW.AT.type, DW.FORM.ref4
290297
var index = dbg_info_buffer.items.len;
291298
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));
293300
// DW.AT.subrange_type
294301
try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_dim));
295302
// DW.AT.type, DW.FORM.ref4
296303
index = dbg_info_buffer.items.len;
297304
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));
299306
// DW.AT.count, DW.FORM.udata
300307
const len = ty.arrayLenIncludingSentinel();
301308
try leb128.writeULEB128(dbg_info_buffer.writer(), len);
@@ -323,7 +330,7 @@ pub const DeclState = struct {
323330
// DW.AT.type, DW.FORM.ref4
324331
var index = dbg_info_buffer.items.len;
325332
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));
327334
// DW.AT.data_member_location, DW.FORM.sdata
328335
const field_off = ty.structFieldOffset(field_index, target);
329336
try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
@@ -354,7 +361,7 @@ pub const DeclState = struct {
354361
// DW.AT.type, DW.FORM.ref4
355362
var index = dbg_info_buffer.items.len;
356363
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));
358365
// DW.AT.data_member_location, DW.FORM.sdata
359366
const field_off = ty.structFieldOffset(field_index, target);
360367
try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
@@ -434,7 +441,7 @@ pub const DeclState = struct {
434441
// DW.AT.type, DW.FORM.ref4
435442
const inner_union_index = dbg_info_buffer.items.len;
436443
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);
438445
// DW.AT.data_member_location, DW.FORM.sdata
439446
try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset);
440447
}
@@ -461,7 +468,7 @@ pub const DeclState = struct {
461468
// DW.AT.type, DW.FORM.ref4
462469
const index = dbg_info_buffer.items.len;
463470
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));
465472
// DW.AT.data_member_location, DW.FORM.sdata
466473
try dbg_info_buffer.append(0);
467474
}
@@ -478,7 +485,7 @@ pub const DeclState = struct {
478485
// DW.AT.type, DW.FORM.ref4
479486
const index = dbg_info_buffer.items.len;
480487
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));
482489
// DW.AT.data_member_location, DW.FORM.sdata
483490
try leb128.writeULEB128(dbg_info_buffer.writer(), tag_offset);
484491

@@ -521,7 +528,7 @@ pub const DeclState = struct {
521528
// DW.AT.type, DW.FORM.ref4
522529
var index = dbg_info_buffer.items.len;
523530
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));
525532
// DW.AT.data_member_location, DW.FORM.sdata
526533
try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off);
527534

@@ -534,7 +541,7 @@ pub const DeclState = struct {
534541
// DW.AT.type, DW.FORM.ref4
535542
index = dbg_info_buffer.items.len;
536543
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));
538545
// DW.AT.data_member_location, DW.FORM.sdata
539546
try leb128.writeULEB128(dbg_info_buffer.writer(), error_off);
540547

@@ -556,7 +563,9 @@ pub const AbbrevEntry = struct {
556563
};
557564

558565
pub 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,
560569
atom: *const Atom,
561570
offset: u32,
562571
addend: u32,
@@ -740,12 +749,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl: *Module.Decl) !DeclState
740749
.wasm => &decl.link.wasm.dbg_info_atom,
741750
else => unreachable,
742751
};
743-
try decl_state.addTypeReloc(
744-
atom,
745-
fn_ret_type,
746-
@intCast(u32, dbg_info_buffer.items.len),
747-
null,
748-
);
752+
try decl_state.addTypeRelocGlobal(atom, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len));
749753
dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4
750754
}
751755

@@ -1036,30 +1040,39 @@ pub fn commitDeclState(
10361040
try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));
10371041

10381042
while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
1039-
const symbol = decl_state.abbrev_table.items[reloc.target];
1040-
const ty = symbol.@"type";
1041-
const deferred: bool = blk: {
1042-
if (ty.isAnyError()) break :blk true;
1043-
switch (ty.tag()) {
1044-
.error_set_inferred => {
1045-
if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;
1046-
},
1047-
else => {},
1043+
if (reloc.target) |target| {
1044+
const symbol = decl_state.abbrev_table.items[target];
1045+
const ty = symbol.@"type";
1046+
const deferred: bool = blk: {
1047+
if (ty.isAnyError()) break :blk true;
1048+
switch (ty.tag()) {
1049+
.error_set_inferred => {
1050+
if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;
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+
);
10481070
}
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-
});
10581071
} else {
10591072
mem.writeInt(
10601073
u32,
10611074
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,
10631076
target_endian,
10641077
);
10651078
}

0 commit comments

Comments
 (0)