authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-30 19:07:36+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-30 19:07:36+02:00
logaaca4ff74dab5d749cd292d31957ce19ab5901c7
treea5aae705179667dc378293c321faf8230649d481
parentd997ddaa102bb9ba5f1e8480b8c78f7d102b5512
parenta1a9d7440ca7b33a73ef7d3b4ee450271337f96f
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21254 from jacobly0/fix-dwarf

Dwarf: fix issues with emitted debug info

3 files changed, 35 insertions(+), 65 deletions(-)

src/link/Dwarf.zig+19-18
...@@ -2593,6 +2593,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2593,6 +2593,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2593 decl_struct: {2593 decl_struct: {
2594 if (loaded_struct.zir_index == .none) break :decl_struct;2594 if (loaded_struct.zir_index == .none) break :decl_struct;
25952595
2596 const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?;
2597 if (type_inst_info.file != inst_info.file) break :decl_struct;
2598
2596 const value_inst = value_inst: {2599 const value_inst = value_inst: {
2597 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;2600 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2598 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));2601 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
...@@ -2608,7 +2611,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2608,7 +2611,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2608 };2611 };
2609 break :value_inst value_inst;2612 break :value_inst value_inst;
2610 };2613 };
2611 const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?;
2612 if (type_inst_info.inst != value_inst) break :decl_struct;2614 if (type_inst_info.inst != value_inst) break :decl_struct;
26132615
2614 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2616 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
...@@ -2623,6 +2625,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2623,6 +2625,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2623 type_gop.value_ptr.* = nav_gop.value_ptr.*;2625 type_gop.value_ptr.* = nav_gop.value_ptr.*;
2624 }2626 }
2625 wip_nav.entry = nav_gop.value_ptr.*;2627 wip_nav.entry = nav_gop.value_ptr.*;
2628
2626 const diw = wip_nav.debug_info.writer(dwarf.gpa);2629 const diw = wip_nav.debug_info.writer(dwarf.gpa);
26272630
2628 switch (loaded_struct.layout) {2631 switch (loaded_struct.layout) {
...@@ -2714,6 +2717,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2714,6 +2717,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2714 decl_enum: {2717 decl_enum: {
2715 if (loaded_enum.zir_index == .none) break :decl_enum;2718 if (loaded_enum.zir_index == .none) break :decl_enum;
27162719
2720 const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;
2721 if (type_inst_info.file != inst_info.file) break :decl_enum;
2722
2717 const value_inst = value_inst: {2723 const value_inst = value_inst: {
2718 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;2724 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2719 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));2725 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
...@@ -2729,7 +2735,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2729,7 +2735,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2729 };2735 };
2730 break :value_inst value_inst;2736 break :value_inst value_inst;
2731 };2737 };
2732 const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;
2733 if (type_inst_info.inst != value_inst) break :decl_enum;2738 if (type_inst_info.inst != value_inst) break :decl_enum;
27342739
2735 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2740 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
...@@ -2797,6 +2802,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2797,6 +2802,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2797 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };2802 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
27982803
2799 decl_union: {2804 decl_union: {
2805 const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;
2806 if (type_inst_info.file != inst_info.file) break :decl_union;
2807
2800 const value_inst = value_inst: {2808 const value_inst = value_inst: {
2801 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;2809 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2802 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));2810 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
...@@ -2812,7 +2820,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2812,7 +2820,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2812 };2820 };
2813 break :value_inst value_inst;2821 break :value_inst value_inst;
2814 };2822 };
2815 const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;
2816 if (type_inst_info.inst != value_inst) break :decl_union;2823 if (type_inst_info.inst != value_inst) break :decl_union;
28172824
2818 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2825 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
...@@ -2872,9 +2879,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2872,9 +2879,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2872 }2879 }
2873 }2880 }
2874 try uleb128(diw, @intFromEnum(AbbrevCode.null));2881 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2875
2876 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
2877 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
2878 } else for (0..loaded_union.field_types.len) |field_index| {2882 } else for (0..loaded_union.field_types.len) |field_index| {
2879 try wip_nav.abbrevCode(.untagged_union_field);2883 try wip_nav.abbrevCode(.untagged_union_field);
2880 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));2884 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
...@@ -2919,6 +2923,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2919,6 +2923,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2919 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };2923 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
29202924
2921 decl_opaque: {2925 decl_opaque: {
2926 const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;
2927 if (type_inst_info.file != inst_info.file) break :decl_opaque;
2928
2922 const value_inst = value_inst: {2929 const value_inst = value_inst: {
2923 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;2930 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2924 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));2931 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
...@@ -2934,7 +2941,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2934,7 +2941,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2934 };2941 };
2935 break :value_inst value_inst;2942 break :value_inst value_inst;
2936 };2943 };
2937 const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;
2938 if (type_inst_info.inst != value_inst) break :decl_opaque;2944 if (type_inst_info.inst != value_inst) break :decl_opaque;
29392945
2940 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2946 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
...@@ -3381,14 +3387,12 @@ fn updateType(...@@ -3381,14 +3387,12 @@ fn updateType(
3381 .Kernel, .Fragment, .Vertex => .nocall,3387 .Kernel, .Fragment, .Vertex => .nocall,
3382 })));3388 })));
3383 try wip_nav.refType(Type.fromInterned(func_type.return_type));3389 try wip_nav.refType(Type.fromInterned(func_type.return_type));
3384 if (!is_nullary) {3390 for (0..func_type.param_types.len) |param_index| {
3385 for (0..func_type.param_types.len) |param_index| {3391 try wip_nav.abbrevCode(.func_type_param);
3386 try wip_nav.abbrevCode(.func_type_param);3392 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
3387 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
3388 }
3389 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
3390 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3391 }3393 }
3394 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
3395 if (!is_nullary) try uleb128(diw, @intFromEnum(AbbrevCode.null));
3392 },3396 },
3393 .error_set_type => |error_set_type| {3397 .error_set_type => |error_set_type| {
3394 try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .enum_type else .empty_enum_type);3398 try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .enum_type else .empty_enum_type);
...@@ -3643,9 +3647,6 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3643,9 +3647,6 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3643 }3647 }
3644 }3648 }
3645 try uleb128(diw, @intFromEnum(AbbrevCode.null));3649 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3646
3647 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
3648 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
3649 } else for (0..loaded_union.field_types.len) |field_index| {3650 } else for (0..loaded_union.field_types.len) |field_index| {
3650 try wip_nav.abbrevCode(.untagged_union_field);3651 try wip_nav.abbrevCode(.untagged_union_field);
3651 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));3652 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
...@@ -3824,7 +3825,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3824,7 +3825,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3824 sleb128(header.fixedWriter(), dwarf.debug_frame.header.data_alignment_factor) catch unreachable;3825 sleb128(header.fixedWriter(), dwarf.debug_frame.header.data_alignment_factor) catch unreachable;
3825 uleb128(header.fixedWriter(), dwarf.debug_frame.header.return_address_register) catch unreachable;3826 uleb128(header.fixedWriter(), dwarf.debug_frame.header.return_address_register) catch unreachable;
3826 uleb128(header.fixedWriter(), 1) catch unreachable;3827 uleb128(header.fixedWriter(), 1) catch unreachable;
3827 header.appendAssumeCapacity(0x10 | 0x08 | 0x03);3828 header.appendAssumeCapacity(DW.EH.PE.pcrel | DW.EH.PE.sdata4);
3828 header.appendAssumeCapacity(DW.CFA.def_cfa_sf);3829 header.appendAssumeCapacity(DW.CFA.def_cfa_sf);
3829 uleb128(header.fixedWriter(), Register.rsp.dwarfNum()) catch unreachable;3830 uleb128(header.fixedWriter(), Register.rsp.dwarfNum()) catch unreachable;
3830 sleb128(header.fixedWriter(), -1) catch unreachable;3831 sleb128(header.fixedWriter(), -1) catch unreachable;
src/link/Elf/eh_frame.zig+10-23
...@@ -482,19 +482,24 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {...@@ -482,19 +482,24 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
482 const gpa = comp.gpa;482 const gpa = comp.gpa;
483483
484 try writer.writeByte(1); // version484 try writer.writeByte(1); // version
485 try writer.writeByte(EH_PE.pcrel | EH_PE.sdata4);485 try writer.writeByte(DW_EH_PE.pcrel | DW_EH_PE.sdata4);
486 try writer.writeByte(EH_PE.udata4);486 try writer.writeByte(DW_EH_PE.udata4);
487 try writer.writeByte(EH_PE.datarel | EH_PE.sdata4);487 try writer.writeByte(DW_EH_PE.datarel | DW_EH_PE.sdata4);
488488
489 const shdrs = elf_file.sections.items(.shdr);489 const shdrs = elf_file.sections.items(.shdr);
490 const eh_frame_shdr = shdrs[elf_file.eh_frame_section_index.?];490 const eh_frame_shdr = shdrs[elf_file.eh_frame_section_index.?];
491 const eh_frame_hdr_shdr = shdrs[elf_file.eh_frame_hdr_section_index.?];491 const eh_frame_hdr_shdr = shdrs[elf_file.eh_frame_hdr_section_index.?];
492 const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8)));492 const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8)));
493 const existing_size = existing_size: {
494 const zo = elf_file.zigObjectPtr() orelse break :existing_size 0;
495 const sym = zo.symbol(zo.eh_frame_index orelse break :existing_size 0);
496 break :existing_size sym.atom(elf_file).?.size;
497 };
493 try writer.writeInt(498 try writer.writeInt(
494 u32,499 u32,
495 @as(u32, @bitCast(@as(500 @as(u32, @bitCast(@as(
496 i32,501 i32,
497 @truncate(@as(i64, @intCast(eh_frame_shdr.sh_addr)) - @as(i64, @intCast(eh_frame_hdr_shdr.sh_addr)) - 4),502 @truncate(@as(i64, @intCast(eh_frame_shdr.sh_addr + existing_size)) - @as(i64, @intCast(eh_frame_hdr_shdr.sh_addr)) - 4),
498 ))),503 ))),
499 .little,504 .little,
500 );505 );
...@@ -543,25 +548,6 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {...@@ -543,25 +548,6 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
543548
544const eh_frame_hdr_header_size: usize = 12;549const eh_frame_hdr_header_size: usize = 12;
545550
546const EH_PE = struct {
547 pub const absptr = 0x00;
548 pub const uleb128 = 0x01;
549 pub const udata2 = 0x02;
550 pub const udata4 = 0x03;
551 pub const udata8 = 0x04;
552 pub const sleb128 = 0x09;
553 pub const sdata2 = 0x0A;
554 pub const sdata4 = 0x0B;
555 pub const sdata8 = 0x0C;
556 pub const pcrel = 0x10;
557 pub const textrel = 0x20;
558 pub const datarel = 0x30;
559 pub const funcrel = 0x40;
560 pub const aligned = 0x50;
561 pub const indirect = 0x80;
562 pub const omit = 0xFF;
563};
564
565const x86_64 = struct {551const x86_64 = struct {
566 fn resolveReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela, source: i64, target: i64, data: []u8) !void {552 fn resolveReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela, source: i64, target: i64, data: []u8) !void {
567 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());553 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
...@@ -619,6 +605,7 @@ const relocation = @import("relocation.zig");...@@ -619,6 +605,7 @@ const relocation = @import("relocation.zig");
619605
620const Allocator = std.mem.Allocator;606const Allocator = std.mem.Allocator;
621const Atom = @import("Atom.zig");607const Atom = @import("Atom.zig");
608const DW_EH_PE = std.dwarf.EH.PE;
622const Elf = @import("../Elf.zig");609const Elf = @import("../Elf.zig");
623const Object = @import("Object.zig");610const Object = @import("Object.zig");
624const Symbol = @import("Symbol.zig");611const Symbol = @import("Symbol.zig");
src/link/MachO/eh_frame.zig+6-24
...@@ -29,22 +29,22 @@ pub const Cie = struct {...@@ -29,22 +29,22 @@ pub const Cie = struct {
29 for (aug[1..]) |ch| switch (ch) {29 for (aug[1..]) |ch| switch (ch) {
30 'R' => {30 'R' => {
31 const enc = try reader.readByte();31 const enc = try reader.readByte();
32 if (enc & 0xf != EH_PE.absptr or enc & EH_PE.pcrel == 0) {32 if (enc != DW_EH_PE.pcrel | DW_EH_PE.absptr) {
33 @panic("unexpected pointer encoding"); // TODO error33 @panic("unexpected pointer encoding"); // TODO error
34 }34 }
35 },35 },
36 'P' => {36 'P' => {
37 const enc = try reader.readByte();37 const enc = try reader.readByte();
38 if (enc != EH_PE.pcrel | EH_PE.indirect | EH_PE.sdata4) {38 if (enc != DW_EH_PE.pcrel | DW_EH_PE.indirect | DW_EH_PE.sdata4) {
39 @panic("unexpected personality pointer encoding"); // TODO error39 @panic("unexpected personality pointer encoding"); // TODO error
40 }40 }
41 _ = try reader.readInt(u32, .little); // personality pointer41 _ = try reader.readInt(u32, .little); // personality pointer
42 },42 },
43 'L' => {43 'L' => {
44 const enc = try reader.readByte();44 const enc = try reader.readByte();
45 switch (enc & 0xf) {45 switch (enc & DW_EH_PE.type_mask) {
46 EH_PE.sdata4 => cie.lsda_size = .p32,46 DW_EH_PE.sdata4 => cie.lsda_size = .p32,
47 EH_PE.absptr => cie.lsda_size = .p64,47 DW_EH_PE.absptr => cie.lsda_size = .p64,
48 else => unreachable, // TODO error48 else => unreachable, // TODO error
49 }49 }
50 },50 },
...@@ -538,25 +538,6 @@ pub fn writeRelocs(macho_file: *MachO, code: []u8, relocs: []macho.relocation_in...@@ -538,25 +538,6 @@ pub fn writeRelocs(macho_file: *MachO, code: []u8, relocs: []macho.relocation_in
538 assert(relocs.len == i);538 assert(relocs.len == i);
539}539}
540540
541pub const EH_PE = struct {
542 pub const absptr = 0x00;
543 pub const uleb128 = 0x01;
544 pub const udata2 = 0x02;
545 pub const udata4 = 0x03;
546 pub const udata8 = 0x04;
547 pub const sleb128 = 0x09;
548 pub const sdata2 = 0x0A;
549 pub const sdata4 = 0x0B;
550 pub const sdata8 = 0x0C;
551 pub const pcrel = 0x10;
552 pub const textrel = 0x20;
553 pub const datarel = 0x30;
554 pub const funcrel = 0x40;
555 pub const aligned = 0x50;
556 pub const indirect = 0x80;
557 pub const omit = 0xFF;
558};
559
560const assert = std.debug.assert;541const assert = std.debug.assert;
561const leb = std.leb;542const leb = std.leb;
562const macho = std.macho;543const macho = std.macho;
...@@ -567,6 +548,7 @@ const trace = @import("../../tracy.zig").trace;...@@ -567,6 +548,7 @@ const trace = @import("../../tracy.zig").trace;
567548
568const Allocator = std.mem.Allocator;549const Allocator = std.mem.Allocator;
569const Atom = @import("Atom.zig");550const Atom = @import("Atom.zig");
551const DW_EH_PE = std.dwarf.EH.PE;
570const File = @import("file.zig").File;552const File = @import("file.zig").File;
571const MachO = @import("../MachO.zig");553const MachO = @import("../MachO.zig");
572const Object = @import("Object.zig");554const Object = @import("Object.zig");