| ... | ... | @@ -783,8 +783,9 @@ pub const abbrev_compile_unit = 1; |
| 783 | 783 | pub const abbrev_subprogram = 2; |
| 784 | 784 | pub const abbrev_subprogram_retvoid = 3; |
| 785 | 785 | pub const abbrev_base_type = 4; |
| 786 | | pub const abbrev_pad1 = 5; |
| 787 | | pub const abbrev_parameter = 6; |
| 786 | pub const abbrev_ptr_type = 5; |
| 787 | pub const abbrev_pad1 = 6; |
| 788 | pub const abbrev_parameter = 7; |
| 788 | 789 | |
| 789 | 790 | pub fn flush(self: *Elf, comp: *Compilation) !void { |
| 790 | 791 | if (self.base.options.emit == null) { |
| ... | ... | @@ -871,9 +872,21 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 871 | 872 | DW.AT.byte_size, |
| 872 | 873 | DW.FORM.data1, |
| 873 | 874 | DW.AT.name, |
| 874 | | DW.FORM.string, 0, 0, // table sentinel |
| 875 | | abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header |
| 876 | | 0, 0, // table sentinel |
| 875 | DW.FORM.string, |
| 876 | 0, |
| 877 | 0, // table sentinel |
| 878 | abbrev_ptr_type, |
| 879 | DW.TAG.pointer_type, |
| 880 | DW.CHILDREN.no, // header |
| 881 | DW.AT.type, |
| 882 | DW.FORM.ref4, |
| 883 | 0, |
| 884 | 0, // table sentinel |
| 885 | abbrev_pad1, |
| 886 | DW.TAG.unspecified_type, |
| 887 | DW.CHILDREN.no, // header |
| 888 | 0, |
| 889 | 0, // table sentinel |
| 877 | 890 | abbrev_parameter, |
| 878 | 891 | DW.TAG.formal_parameter, DW.CHILDREN.no, // header |
| 879 | 892 | DW.AT.location, DW.FORM.exprloc, |
| ... | ... | @@ -2309,8 +2322,7 @@ pub fn freeDecl(self: *Elf, decl: *Module.Decl) void { |
| 2309 | 2322 | } |
| 2310 | 2323 | |
| 2311 | 2324 | fn deinitRelocs(gpa: Allocator, table: *File.DbgInfoTypeRelocsTable) void { |
| 2312 | | var it = table.valueIterator(); |
| 2313 | | while (it.next()) |value| { |
| 2325 | for (table.values()) |*value| { |
| 2314 | 2326 | value.relocs.deinit(gpa); |
| 2315 | 2327 | } |
| 2316 | 2328 | table.deinit(gpa); |
| ... | ... | @@ -2387,10 +2399,12 @@ fn finishUpdateDecl( |
| 2387 | 2399 | // the buffer, so we have to do it before computing the offset, and we can't perform the actual |
| 2388 | 2400 | // relocations yet. |
| 2389 | 2401 | { |
| 2390 | | var it = dbg_info_type_relocs.iterator(); |
| 2391 | | while (it.next()) |entry| { |
| 2392 | | entry.value_ptr.off = @intCast(u32, dbg_info_buffer.items.len); |
| 2393 | | try self.addDbgInfoType(entry.key_ptr.*, dbg_info_buffer); |
| 2402 | var it: usize = 0; |
| 2403 | while (it < dbg_info_type_relocs.count()) : (it += 1) { |
| 2404 | const ty = dbg_info_type_relocs.keys()[it]; |
| 2405 | const value_ptr = dbg_info_type_relocs.getPtr(ty).?; |
| 2406 | value_ptr.off = @intCast(u32, dbg_info_buffer.items.len); |
| 2407 | try self.addDbgInfoType(ty, dbg_info_buffer, dbg_info_type_relocs); |
| 2394 | 2408 | } |
| 2395 | 2409 | } |
| 2396 | 2410 | |
| ... | ... | @@ -2401,8 +2415,7 @@ fn finishUpdateDecl( |
| 2401 | 2415 | |
| 2402 | 2416 | { |
| 2403 | 2417 | // Now that we have the offset assigned we can finally perform type relocations. |
| 2404 | | var it = dbg_info_type_relocs.valueIterator(); |
| 2405 | | while (it.next()) |value| { |
| 2418 | for (dbg_info_type_relocs.values()) |value| { |
| 2406 | 2419 | for (value.relocs.items) |off| { |
| 2407 | 2420 | mem.writeInt( |
| 2408 | 2421 | u32, |
| ... | ... | @@ -2706,7 +2719,14 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 2706 | 2719 | } |
| 2707 | 2720 | |
| 2708 | 2721 | /// Asserts the type has codegen bits. |
| 2709 | | fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !void { |
| 2722 | fn addDbgInfoType( |
| 2723 | self: *Elf, |
| 2724 | ty: Type, |
| 2725 | dbg_info_buffer: *std.ArrayList(u8), |
| 2726 | dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable, |
| 2727 | ) error{OutOfMemory}!void { |
| 2728 | var reloc: ?struct { ty: Type, reloc: u32 } = null; |
| 2729 | |
| 2710 | 2730 | switch (ty.zigTypeTag()) { |
| 2711 | 2731 | .Void => unreachable, |
| 2712 | 2732 | .NoReturn => unreachable, |
| ... | ... | @@ -2747,11 +2767,34 @@ fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !vo |
| 2747 | 2767 | try dbg_info_buffer.append(abbrev_pad1); |
| 2748 | 2768 | } |
| 2749 | 2769 | }, |
| 2770 | .Pointer => blk: { |
| 2771 | if (ty.isSlice()) { |
| 2772 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); |
| 2773 | try dbg_info_buffer.append(abbrev_pad1); |
| 2774 | break :blk; |
| 2775 | } |
| 2776 | try dbg_info_buffer.ensureUnusedCapacity(5); |
| 2777 | dbg_info_buffer.appendAssumeCapacity(abbrev_ptr_type); |
| 2778 | const index = dbg_info_buffer.items.len; |
| 2779 | try dbg_info_buffer.resize(index + 4); // DW.AT.type, DW.FORM.ref4 |
| 2780 | reloc = .{ .ty = ty.childType(), .reloc = @intCast(u32, index) }; |
| 2781 | }, |
| 2750 | 2782 | else => { |
| 2751 | 2783 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); |
| 2752 | 2784 | try dbg_info_buffer.append(abbrev_pad1); |
| 2753 | 2785 | }, |
| 2754 | 2786 | } |
| 2787 | |
| 2788 | if (reloc) |rel| { |
| 2789 | const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, rel.ty); |
| 2790 | if (!gop.found_existing) { |
| 2791 | gop.value_ptr.* = .{ |
| 2792 | .off = undefined, |
| 2793 | .relocs = .{}, |
| 2794 | }; |
| 2795 | } |
| 2796 | try gop.value_ptr.relocs.append(self.base.allocator, rel.reloc); |
| 2797 | } |
| 2755 | 2798 | } |
| 2756 | 2799 | |
| 2757 | 2800 | fn updateDeclDebugInfoAllocation(self: *Elf, text_block: *TextBlock, len: u32) !void { |