| author | |
| committer | |
| log | aeaffd42f6d1c8fc92fa7669a579a8e6c46eb641 |
| tree | aad5e99e972b3cb4fe3b92aaf355ea86037de334 |
| parent | f2f1bb7cb675fc14dc7754f06329b5780091baaf |
Add handling for these additional `MCValue`s:
* `.immediate` - lower to `DW.OP.consts` or `DW.OP.constu` depending
on signedness followed by popping off the DWARF stack with
`DW.OP.stack_value`
* `.undef` - lower to `DW.OP.implicit_value`
* `.none` - lower to `DW.OP.lit0` followed by popping off the DWARF
stack with `DW.OP.stack_value`
For any remaining unhandled case, we generate `DW.OP.nop` in order
not to mess up remaining DWARF info.2 files changed, 54 insertions(+), 5 deletions(-)
src/arch/x86_64/CodeGen.zig+47-1| ... | @@ -4370,6 +4370,7 @@ fn genVarDbgInfo( | ... | @@ -4370,6 +4370,7 @@ fn genVarDbgInfo( |
| 4370 | .dwarf => |dw| { | 4370 | .dwarf => |dw| { |
| 4371 | const dbg_info = &dw.dbg_info; | 4371 | const dbg_info = &dw.dbg_info; |
| 4372 | try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable)); | 4372 | try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable)); |
| 4373 | const endian = self.target.cpu.arch.endian(); | ||
| 4373 | 4374 | ||
| 4374 | switch (mcv) { | 4375 | switch (mcv) { |
| 4375 | .register => |reg| { | 4376 | .register => |reg| { |
| ... | @@ -4390,7 +4391,6 @@ fn genVarDbgInfo( | ... | @@ -4390,7 +4391,6 @@ fn genVarDbgInfo( |
| 4390 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); | 4391 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); |
| 4391 | }, | 4392 | }, |
| 4392 | .memory, .got_load, .direct_load => { | 4393 | .memory, .got_load, .direct_load => { |
| 4393 | const endian = self.target.cpu.arch.endian(); | ||
| 4394 | const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); | 4394 | const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); |
| 4395 | const is_ptr = switch (tag) { | 4395 | const is_ptr = switch (tag) { |
| 4396 | .dbg_var_ptr => true, | 4396 | .dbg_var_ptr => true, |
| ... | @@ -4425,7 +4425,53 @@ fn genVarDbgInfo( | ... | @@ -4425,7 +4425,53 @@ fn genVarDbgInfo( |
| 4425 | else => {}, | 4425 | else => {}, |
| 4426 | } | 4426 | } |
| 4427 | }, | 4427 | }, |
| 4428 | .immediate => |x| { | ||
| 4429 | const signedness: std.builtin.Signedness = blk: { | ||
| 4430 | if (ty.zigTypeTag() != .Int) break :blk .unsigned; | ||
| 4431 | break :blk ty.intInfo(self.target.*).signedness; | ||
| 4432 | }; | ||
| 4433 | try dbg_info.ensureUnusedCapacity(2); | ||
| 4434 | const fixup = dbg_info.items.len; | ||
| 4435 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | ||
| 4436 | 1, | ||
| 4437 | switch (signedness) { | ||
| 4438 | .signed => DW.OP.consts, | ||
| 4439 | .unsigned => DW.OP.constu, | ||
| 4440 | }, | ||
| 4441 | }); | ||
| 4442 | switch (signedness) { | ||
| 4443 | .signed => try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x)), | ||
| 4444 | .unsigned => try leb128.writeULEB128(dbg_info.writer(), x), | ||
| 4445 | } | ||
| 4446 | try dbg_info.append(DW.OP.stack_value); | ||
| 4447 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); | ||
| 4448 | }, | ||
| 4449 | .undef => { | ||
| 4450 | // DW.AT.location, DW.FORM.exprloc | ||
| 4451 | // uleb128(exprloc_len) | ||
| 4452 | // DW.OP.implicit_value uleb128(len_of_bytes) bytes | ||
| 4453 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); | ||
| 4454 | var implicit_value_len = std.ArrayList(u8).init(self.gpa); | ||
| 4455 | defer implicit_value_len.deinit(); | ||
| 4456 | try leb128.writeULEB128(implicit_value_len.writer(), abi_size); | ||
| 4457 | const total_exprloc_len = 1 + implicit_value_len.items.len + abi_size; | ||
| 4458 | try leb128.writeULEB128(dbg_info.writer(), total_exprloc_len); | ||
| 4459 | try dbg_info.ensureUnusedCapacity(total_exprloc_len); | ||
| 4460 | dbg_info.appendAssumeCapacity(DW.OP.implicit_value); | ||
| 4461 | dbg_info.appendSliceAssumeCapacity(implicit_value_len.items); | ||
| 4462 | dbg_info.appendNTimesAssumeCapacity(0xaa, abi_size); | ||
| 4463 | }, | ||
| 4464 | .none => { | ||
| 4465 | try dbg_info.ensureUnusedCapacity(3); | ||
| 4466 | dbg_info.appendSliceAssumeCapacity(&[3]u8{ // DW.AT.location, DW.FORM.exprloc | ||
| 4467 | 2, DW.OP.lit0, DW.OP.stack_value, | ||
| 4468 | }); | ||
| 4469 | }, | ||
| 4428 | else => { | 4470 | else => { |
| 4471 | try dbg_info.ensureUnusedCapacity(2); | ||
| 4472 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | ||
| 4473 | 1, DW.OP.nop, | ||
| 4474 | }); | ||
| 4429 | log.debug("TODO generate debug info for {}", .{mcv}); | 4475 | log.debug("TODO generate debug info for {}", .{mcv}); |
| 4430 | }, | 4476 | }, |
| 4431 | } | 4477 | } |
src/link/Dwarf.zig+7-4| ... | @@ -102,7 +102,7 @@ pub const DeclState = struct { | ... | @@ -102,7 +102,7 @@ pub const DeclState = struct { |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | pub fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void { | 104 | pub fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void { |
| 105 | log.debug("{x}: target sym @{d}, via GOT {}", .{ offset, target, is_ptr }); | 105 | log.debug("{x}: target sym %{d}, via GOT {}", .{ offset, target, is_ptr }); |
| 106 | try self.exprloc_relocs.append(self.gpa, .{ | 106 | try self.exprloc_relocs.append(self.gpa, .{ |
| 107 | .@"type" = if (is_ptr) .got_load else .direct_load, | 107 | .@"type" = if (is_ptr) .got_load else .direct_load, |
| 108 | .target = target, | 108 | .target = target, |
| ... | @@ -135,7 +135,7 @@ pub const DeclState = struct { | ... | @@ -135,7 +135,7 @@ pub const DeclState = struct { |
| 135 | .@"type" = ty, | 135 | .@"type" = ty, |
| 136 | .offset = undefined, | 136 | .offset = undefined, |
| 137 | }); | 137 | }); |
| 138 | log.debug("@{d}: {}", .{ sym_index, ty.fmtDebug() }); | 138 | log.debug("%{d}: {}", .{ sym_index, ty.fmtDebug() }); |
| 139 | try self.abbrev_resolver.putNoClobberContext(self.gpa, ty, sym_index, .{ | 139 | try self.abbrev_resolver.putNoClobberContext(self.gpa, ty, sym_index, .{ |
| 140 | .mod = self.mod, | 140 | .mod = self.mod, |
| 141 | }); | 141 | }); |
| ... | @@ -143,7 +143,7 @@ pub const DeclState = struct { | ... | @@ -143,7 +143,7 @@ pub const DeclState = struct { |
| 143 | .mod = self.mod, | 143 | .mod = self.mod, |
| 144 | }).?; | 144 | }).?; |
| 145 | }; | 145 | }; |
| 146 | log.debug("{x}: @{d} + 0", .{ offset, resolv }); | 146 | log.debug("{x}: %{d} + 0", .{ offset, resolv }); |
| 147 | try self.abbrev_relocs.append(self.gpa, .{ | 147 | try self.abbrev_relocs.append(self.gpa, .{ |
| 148 | .target = resolv, | 148 | .target = resolv, |
| 149 | .atom = atom, | 149 | .atom = atom, |
| ... | @@ -1056,6 +1056,7 @@ pub fn commitDeclState( | ... | @@ -1056,6 +1056,7 @@ pub fn commitDeclState( |
| 1056 | break :blk false; | 1056 | break :blk false; |
| 1057 | }; | 1057 | }; |
| 1058 | if (deferred) { | 1058 | if (deferred) { |
| 1059 | log.debug("resolving %{d} deferred until flush", .{target}); | ||
| 1059 | try self.global_abbrev_relocs.append(gpa, .{ | 1060 | try self.global_abbrev_relocs.append(gpa, .{ |
| 1060 | .target = null, | 1061 | .target = null, |
| 1061 | .offset = reloc.offset, | 1062 | .offset = reloc.offset, |
| ... | @@ -1063,10 +1064,12 @@ pub fn commitDeclState( | ... | @@ -1063,10 +1064,12 @@ pub fn commitDeclState( |
| 1063 | .addend = reloc.addend, | 1064 | .addend = reloc.addend, |
| 1064 | }); | 1065 | }); |
| 1065 | } else { | 1066 | } else { |
| 1067 | const value = symbol.atom.off + symbol.offset + reloc.addend; | ||
| 1068 | log.debug("{x}: [() => {x}] (%{d}, '{}')", .{ reloc.offset, value, target, ty.fmtDebug() }); | ||
| 1066 | mem.writeInt( | 1069 | mem.writeInt( |
| 1067 | u32, | 1070 | u32, |
| 1068 | dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)], | 1071 | dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)], |
| 1069 | symbol.atom.off + symbol.offset + reloc.addend, | 1072 | value, |
| 1070 | target_endian, | 1073 | target_endian, |
| 1071 | ); | 1074 | ); |
| 1072 | } | 1075 | } |