From f0c0f697a6be87f1e926a03b6a61579cddde08e7 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 30 Aug 2024 08:20:42 -0400 Subject: [PATCH 1/3] Dwarf: fix zir inst index comparison not checking the file --- src/link/Dwarf.zig | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index ab59dd2a2e..934baf1e28 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -2593,6 +2593,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool decl_struct: { if (loaded_struct.zir_index == .none) break :decl_struct; + const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :decl_struct; + const value_inst = value_inst: { const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; 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 }; break :value_inst value_inst; }; - const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?; if (type_inst_info.inst != value_inst) break :decl_struct; 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 type_gop.value_ptr.* = nav_gop.value_ptr.*; } wip_nav.entry = nav_gop.value_ptr.*; + const diw = wip_nav.debug_info.writer(dwarf.gpa); switch (loaded_struct.layout) { @@ -2714,6 +2717,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool decl_enum: { if (loaded_enum.zir_index == .none) break :decl_enum; + const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :decl_enum; + const value_inst = value_inst: { const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; 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 }; break :value_inst value_inst; }; - const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?; if (type_inst_info.inst != value_inst) break :decl_enum; 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 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; decl_union: { + const type_inst_info = loaded_union.zir_index.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :decl_union; + const value_inst = value_inst: { const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; 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 }; break :value_inst value_inst; }; - const type_inst_info = loaded_union.zir_index.resolveFull(ip).?; if (type_inst_info.inst != value_inst) break :decl_union; 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 } } try uleb128(diw, @intFromEnum(AbbrevCode.null)); - - if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag) - try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty); } else for (0..loaded_union.field_types.len) |field_index| { try wip_nav.abbrevCode(.untagged_union_field); 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 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; decl_opaque: { + const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :decl_opaque; + const value_inst = value_inst: { const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; 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 }; break :value_inst value_inst; }; - const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?; if (type_inst_info.inst != value_inst) break :decl_opaque; const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); @@ -3381,14 +3387,12 @@ fn updateType( .Kernel, .Fragment, .Vertex => .nocall, }))); try wip_nav.refType(Type.fromInterned(func_type.return_type)); - if (!is_nullary) { - for (0..func_type.param_types.len) |param_index| { - try wip_nav.abbrevCode(.func_type_param); - try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index])); - } - if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args); - try uleb128(diw, @intFromEnum(AbbrevCode.null)); + for (0..func_type.param_types.len) |param_index| { + try wip_nav.abbrevCode(.func_type_param); + try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index])); } + if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args); + if (!is_nullary) try uleb128(diw, @intFromEnum(AbbrevCode.null)); }, .error_set_type => |error_set_type| { 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 } } try uleb128(diw, @intFromEnum(AbbrevCode.null)); - - if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag) - try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty); } else for (0..loaded_union.field_types.len) |field_index| { try wip_nav.abbrevCode(.untagged_union_field); try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip)); From 7305184203dd94fd48da69f8a468b3094b848533 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 30 Aug 2024 08:58:06 -0400 Subject: [PATCH 2/3] dwarf: share and use `std.dwarf.EH_PE` constants --- src/link/Dwarf.zig | 2 +- src/link/Elf/eh_frame.zig | 26 ++++---------------------- src/link/MachO/eh_frame.zig | 30 ++++++------------------------ 3 files changed, 11 insertions(+), 47 deletions(-) diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 934baf1e28..c3197f7651 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -3825,7 +3825,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { sleb128(header.fixedWriter(), dwarf.debug_frame.header.data_alignment_factor) catch unreachable; uleb128(header.fixedWriter(), dwarf.debug_frame.header.return_address_register) catch unreachable; uleb128(header.fixedWriter(), 1) catch unreachable; - header.appendAssumeCapacity(0x10 | 0x08 | 0x03); + header.appendAssumeCapacity(DW.EH.PE.pcrel | DW.EH.PE.sdata4); header.appendAssumeCapacity(DW.CFA.def_cfa_sf); uleb128(header.fixedWriter(), Register.rsp.dwarfNum()) catch unreachable; sleb128(header.fixedWriter(), -1) catch unreachable; diff --git a/src/link/Elf/eh_frame.zig b/src/link/Elf/eh_frame.zig index fa555e9d2d..bad1dbcc3b 100644 --- a/src/link/Elf/eh_frame.zig +++ b/src/link/Elf/eh_frame.zig @@ -482,9 +482,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { const gpa = comp.gpa; try writer.writeByte(1); // version - try writer.writeByte(EH_PE.pcrel | EH_PE.sdata4); - try writer.writeByte(EH_PE.udata4); - try writer.writeByte(EH_PE.datarel | EH_PE.sdata4); + try writer.writeByte(DW_EH_PE.pcrel | DW_EH_PE.sdata4); + try writer.writeByte(DW_EH_PE.udata4); + try writer.writeByte(DW_EH_PE.datarel | DW_EH_PE.sdata4); const shdrs = elf_file.sections.items(.shdr); const eh_frame_shdr = shdrs[elf_file.eh_frame_section_index.?]; @@ -543,25 +543,6 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { const eh_frame_hdr_header_size: usize = 12; -const EH_PE = struct { - pub const absptr = 0x00; - pub const uleb128 = 0x01; - pub const udata2 = 0x02; - pub const udata4 = 0x03; - pub const udata8 = 0x04; - pub const sleb128 = 0x09; - pub const sdata2 = 0x0A; - pub const sdata4 = 0x0B; - pub const sdata8 = 0x0C; - pub const pcrel = 0x10; - pub const textrel = 0x20; - pub const datarel = 0x30; - pub const funcrel = 0x40; - pub const aligned = 0x50; - pub const indirect = 0x80; - pub const omit = 0xFF; -}; - const x86_64 = struct { fn resolveReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela, source: i64, target: i64, data: []u8) !void { const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); @@ -619,6 +600,7 @@ const relocation = @import("relocation.zig"); const Allocator = std.mem.Allocator; const Atom = @import("Atom.zig"); +const DW_EH_PE = std.dwarf.EH.PE; const Elf = @import("../Elf.zig"); const Object = @import("Object.zig"); const Symbol = @import("Symbol.zig"); diff --git a/src/link/MachO/eh_frame.zig b/src/link/MachO/eh_frame.zig index 46d6aef3e0..ccabffb1dc 100644 --- a/src/link/MachO/eh_frame.zig +++ b/src/link/MachO/eh_frame.zig @@ -29,22 +29,22 @@ pub const Cie = struct { for (aug[1..]) |ch| switch (ch) { 'R' => { const enc = try reader.readByte(); - if (enc & 0xf != EH_PE.absptr or enc & EH_PE.pcrel == 0) { + if (enc != DW_EH_PE.pcrel | DW_EH_PE.absptr) { @panic("unexpected pointer encoding"); // TODO error } }, 'P' => { const enc = try reader.readByte(); - if (enc != EH_PE.pcrel | EH_PE.indirect | EH_PE.sdata4) { + if (enc != DW_EH_PE.pcrel | DW_EH_PE.indirect | DW_EH_PE.sdata4) { @panic("unexpected personality pointer encoding"); // TODO error } _ = try reader.readInt(u32, .little); // personality pointer }, 'L' => { const enc = try reader.readByte(); - switch (enc & 0xf) { - EH_PE.sdata4 => cie.lsda_size = .p32, - EH_PE.absptr => cie.lsda_size = .p64, + switch (enc & DW_EH_PE.type_mask) { + DW_EH_PE.sdata4 => cie.lsda_size = .p32, + DW_EH_PE.absptr => cie.lsda_size = .p64, else => unreachable, // TODO error } }, @@ -538,25 +538,6 @@ pub fn writeRelocs(macho_file: *MachO, code: []u8, relocs: []macho.relocation_in assert(relocs.len == i); } -pub const EH_PE = struct { - pub const absptr = 0x00; - pub const uleb128 = 0x01; - pub const udata2 = 0x02; - pub const udata4 = 0x03; - pub const udata8 = 0x04; - pub const sleb128 = 0x09; - pub const sdata2 = 0x0A; - pub const sdata4 = 0x0B; - pub const sdata8 = 0x0C; - pub const pcrel = 0x10; - pub const textrel = 0x20; - pub const datarel = 0x30; - pub const funcrel = 0x40; - pub const aligned = 0x50; - pub const indirect = 0x80; - pub const omit = 0xFF; -}; - const assert = std.debug.assert; const leb = std.leb; const macho = std.macho; @@ -567,6 +548,7 @@ const trace = @import("../../tracy.zig").trace; const Allocator = std.mem.Allocator; const Atom = @import("Atom.zig"); +const DW_EH_PE = std.dwarf.EH.PE; const File = @import("file.zig").File; const MachO = @import("../MachO.zig"); const Object = @import("Object.zig"); From a1a9d7440ca7b33a73ef7d3b4ee450271337f96f Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 30 Aug 2024 09:01:30 -0400 Subject: [PATCH 3/3] Elf: fix reference from `eh_frame_hdr` to `eh_frame` --- src/link/Elf/eh_frame.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/link/Elf/eh_frame.zig b/src/link/Elf/eh_frame.zig index bad1dbcc3b..d660486010 100644 --- a/src/link/Elf/eh_frame.zig +++ b/src/link/Elf/eh_frame.zig @@ -490,11 +490,16 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { const eh_frame_shdr = shdrs[elf_file.eh_frame_section_index.?]; const eh_frame_hdr_shdr = shdrs[elf_file.eh_frame_hdr_section_index.?]; const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8))); + const existing_size = existing_size: { + const zo = elf_file.zigObjectPtr() orelse break :existing_size 0; + const sym = zo.symbol(zo.eh_frame_index orelse break :existing_size 0); + break :existing_size sym.atom(elf_file).?.size; + }; try writer.writeInt( u32, @as(u32, @bitCast(@as( i32, - @truncate(@as(i64, @intCast(eh_frame_shdr.sh_addr)) - @as(i64, @intCast(eh_frame_hdr_shdr.sh_addr)) - 4), + @truncate(@as(i64, @intCast(eh_frame_shdr.sh_addr + existing_size)) - @as(i64, @intCast(eh_frame_hdr_shdr.sh_addr)) - 4), ))), .little, );