| ... | @@ -784,8 +784,10 @@ pub const abbrev_subprogram = 2; | ... | @@ -784,8 +784,10 @@ pub const abbrev_subprogram = 2; |
| 784 | pub const abbrev_subprogram_retvoid = 3; | 784 | pub const abbrev_subprogram_retvoid = 3; |
| 785 | pub const abbrev_base_type = 4; | 785 | pub const abbrev_base_type = 4; |
| 786 | pub const abbrev_ptr_type = 5; | 786 | pub const abbrev_ptr_type = 5; |
| 787 | pub const abbrev_pad1 = 6; | 787 | pub const abbrev_anon_struct_type = 6; |
| 788 | pub const abbrev_parameter = 7; | 788 | pub const abbrev_struct_member = 7; |
| | 789 | pub const abbrev_pad1 = 8; |
| | 790 | pub const abbrev_parameter = 9; |
| 789 | | 791 | |
| 790 | pub fn flush(self: *Elf, comp: *Compilation) !void { | 792 | pub fn flush(self: *Elf, comp: *Compilation) !void { |
| 791 | if (self.base.options.emit == null) { | 793 | if (self.base.options.emit == null) { |
| ... | @@ -882,6 +884,24 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -882,6 +884,24 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 882 | DW.FORM.ref4, | 884 | DW.FORM.ref4, |
| 883 | 0, | 885 | 0, |
| 884 | 0, // table sentinel | 886 | 0, // table sentinel |
| | 887 | abbrev_anon_struct_type, |
| | 888 | DW.TAG.structure_type, |
| | 889 | DW.CHILDREN.yes, // header |
| | 890 | DW.AT.byte_size, |
| | 891 | DW.FORM.sdata, |
| | 892 | 0, |
| | 893 | 0, // table sentinel |
| | 894 | abbrev_struct_member, |
| | 895 | DW.TAG.member, |
| | 896 | DW.CHILDREN.no, // header |
| | 897 | DW.AT.name, |
| | 898 | DW.FORM.string, |
| | 899 | DW.AT.type, |
| | 900 | DW.FORM.ref4, |
| | 901 | DW.AT.data_member_location, |
| | 902 | DW.FORM.sdata, |
| | 903 | 0, |
| | 904 | 0, // table sentinel |
| 885 | abbrev_pad1, | 905 | abbrev_pad1, |
| 886 | DW.TAG.unspecified_type, | 906 | DW.TAG.unspecified_type, |
| 887 | DW.CHILDREN.no, // header | 907 | DW.CHILDREN.no, // header |
| ... | @@ -2395,6 +2415,16 @@ fn finishUpdateDecl( | ... | @@ -2395,6 +2415,16 @@ fn finishUpdateDecl( |
| 2395 | dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable, | 2415 | dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable, |
| 2396 | dbg_info_buffer: *std.ArrayList(u8), | 2416 | dbg_info_buffer: *std.ArrayList(u8), |
| 2397 | ) !void { | 2417 | ) !void { |
| | 2418 | // We need this for the duration of this function only so that for composite |
| | 2419 | // types such as []const u32, if the type *u32 is non-existent, we create |
| | 2420 | // it synthetically and store the backing bytes in this arena. After we are |
| | 2421 | // done with the relocations, we can safely deinit the entire memory slab. |
| | 2422 | // TODO currently, we do not store the relocations for future use, however, |
| | 2423 | // if that is the case, we should move memory management to a higher scope, |
| | 2424 | // such as linker scope, or whatnot. |
| | 2425 | var dbg_type_arena = std.heap.ArenaAllocator.init(self.base.allocator); |
| | 2426 | defer dbg_type_arena.deinit(); |
| | 2427 | |
| 2398 | // Now we emit the .debug_info types of the Decl. These will count towards the size of | 2428 | // Now we emit the .debug_info types of the Decl. These will count towards the size of |
| 2399 | // the buffer, so we have to do it before computing the offset, and we can't perform the actual | 2429 | // the buffer, so we have to do it before computing the offset, and we can't perform the actual |
| 2400 | // relocations yet. | 2430 | // relocations yet. |
| ... | @@ -2404,7 +2434,7 @@ fn finishUpdateDecl( | ... | @@ -2404,7 +2434,7 @@ fn finishUpdateDecl( |
| 2404 | const ty = dbg_info_type_relocs.keys()[it]; | 2434 | const ty = dbg_info_type_relocs.keys()[it]; |
| 2405 | const value_ptr = dbg_info_type_relocs.getPtr(ty).?; | 2435 | const value_ptr = dbg_info_type_relocs.getPtr(ty).?; |
| 2406 | value_ptr.off = @intCast(u32, dbg_info_buffer.items.len); | 2436 | value_ptr.off = @intCast(u32, dbg_info_buffer.items.len); |
| 2407 | try self.addDbgInfoType(ty, dbg_info_buffer, dbg_info_type_relocs); | 2437 | try self.addDbgInfoType(dbg_type_arena.allocator(), ty, dbg_info_buffer, dbg_info_type_relocs); |
| 2408 | } | 2438 | } |
| 2409 | } | 2439 | } |
| 2410 | | 2440 | |
| ... | @@ -2721,11 +2751,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { | ... | @@ -2721,11 +2751,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 2721 | /// Asserts the type has codegen bits. | 2751 | /// Asserts the type has codegen bits. |
| 2722 | fn addDbgInfoType( | 2752 | fn addDbgInfoType( |
| 2723 | self: *Elf, | 2753 | self: *Elf, |
| | 2754 | arena: Allocator, |
| 2724 | ty: Type, | 2755 | ty: Type, |
| 2725 | dbg_info_buffer: *std.ArrayList(u8), | 2756 | dbg_info_buffer: *std.ArrayList(u8), |
| 2726 | dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable, | 2757 | dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable, |
| 2727 | ) error{OutOfMemory}!void { | 2758 | ) error{OutOfMemory}!void { |
| 2728 | var reloc: ?struct { ty: Type, reloc: u32 } = null; | 2759 | var relocs = std.ArrayList(struct { ty: Type, reloc: u32 }).init(arena); |
| 2729 | | 2760 | |
| 2730 | switch (ty.zigTypeTag()) { | 2761 | switch (ty.zigTypeTag()) { |
| 2731 | .Void => unreachable, | 2762 | .Void => unreachable, |
| ... | @@ -2767,17 +2798,48 @@ fn addDbgInfoType( | ... | @@ -2767,17 +2798,48 @@ fn addDbgInfoType( |
| 2767 | try dbg_info_buffer.append(abbrev_pad1); | 2798 | try dbg_info_buffer.append(abbrev_pad1); |
| 2768 | } | 2799 | } |
| 2769 | }, | 2800 | }, |
| 2770 | .Pointer => blk: { | 2801 | .Pointer => { |
| 2771 | if (ty.isSlice()) { | 2802 | if (ty.isSlice()) { |
| 2772 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); | 2803 | // Slices are anonymous structs: struct { .ptr = *, .len = N } |
| 2773 | try dbg_info_buffer.append(abbrev_pad1); | 2804 | try dbg_info_buffer.ensureUnusedCapacity(23); |
| 2774 | break :blk; | 2805 | // DW.AT.structure_type |
| | 2806 | dbg_info_buffer.appendAssumeCapacity(abbrev_anon_struct_type); |
| | 2807 | // DW.AT.byte_size, DW.FORM.sdata |
| | 2808 | dbg_info_buffer.appendAssumeCapacity(16); |
| | 2809 | // DW.AT.member |
| | 2810 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); |
| | 2811 | // DW.AT.name, DW.FORM.string |
| | 2812 | dbg_info_buffer.appendSliceAssumeCapacity("ptr"); |
| | 2813 | dbg_info_buffer.appendAssumeCapacity(0); |
| | 2814 | // DW.AT.type, DW.FORM.ref4 |
| | 2815 | var index = dbg_info_buffer.items.len; |
| | 2816 | try dbg_info_buffer.resize(index + 4); |
| | 2817 | var buf = try arena.create(Type.SlicePtrFieldTypeBuffer); |
| | 2818 | const ptr_ty = ty.slicePtrFieldType(buf); |
| | 2819 | try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) }); |
| | 2820 | // DW.AT.data_member_location, DW.FORM.sdata |
| | 2821 | dbg_info_buffer.appendAssumeCapacity(0); |
| | 2822 | // DW.AT.member |
| | 2823 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); |
| | 2824 | // DW.AT.name, DW.FORM.string |
| | 2825 | dbg_info_buffer.appendSliceAssumeCapacity("len"); |
| | 2826 | dbg_info_buffer.appendAssumeCapacity(0); |
| | 2827 | // DW.AT.type, DW.FORM.ref4 |
| | 2828 | index = dbg_info_buffer.items.len; |
| | 2829 | try dbg_info_buffer.resize(index + 4); |
| | 2830 | try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) }); |
| | 2831 | // DW.AT.data_member_location, DW.FORM.sdata |
| | 2832 | dbg_info_buffer.appendAssumeCapacity(8); |
| | 2833 | // DW.AT.structure_type delimit children |
| | 2834 | dbg_info_buffer.appendAssumeCapacity(0); |
| | 2835 | } else { |
| | 2836 | try dbg_info_buffer.ensureUnusedCapacity(5); |
| | 2837 | dbg_info_buffer.appendAssumeCapacity(abbrev_ptr_type); |
| | 2838 | // DW.AT.type, DW.FORM.ref4 |
| | 2839 | const index = dbg_info_buffer.items.len; |
| | 2840 | try dbg_info_buffer.resize(index + 4); |
| | 2841 | try relocs.append(.{ .ty = ty.childType(), .reloc = @intCast(u32, index) }); |
| 2775 | } | 2842 | } |
| 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 | }, | 2843 | }, |
| 2782 | else => { | 2844 | else => { |
| 2783 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); | 2845 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); |
| ... | @@ -2785,7 +2847,7 @@ fn addDbgInfoType( | ... | @@ -2785,7 +2847,7 @@ fn addDbgInfoType( |
| 2785 | }, | 2847 | }, |
| 2786 | } | 2848 | } |
| 2787 | | 2849 | |
| 2788 | if (reloc) |rel| { | 2850 | for (relocs.items) |rel| { |
| 2789 | const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, rel.ty); | 2851 | const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, rel.ty); |
| 2790 | if (!gop.found_existing) { | 2852 | if (!gop.found_existing) { |
| 2791 | gop.value_ptr.* = .{ | 2853 | gop.value_ptr.* = .{ |