| author | |
| committer | |
| log | 72992b6513b3c6f5d8bd0abffe0d08a2a7d6e7cd |
| tree | 566f64e6edf9bfe1b43e6bf397ad9bb0cc7d7795 |
| parent | 908f41a67cbd377eb15d07a27778dbbca0a4309f |
| parent | 1252bdd4d63eda5ee70b7f58979b2471c2f83555 |
| signature |
5 files changed, 158 insertions(+), 68 deletions(-)
src/arch/x86_64/Emit.zig+16-2| ... | @@ -1019,7 +1019,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32 | ... | @@ -1019,7 +1019,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32 |
| 1019 | switch (emit.debug_output) { | 1019 | switch (emit.debug_output) { |
| 1020 | .dwarf => |dbg_out| { | 1020 | .dwarf => |dbg_out| { |
| 1021 | try dbg_out.dbg_info.ensureUnusedCapacity(3); | 1021 | try dbg_out.dbg_info.ensureUnusedCapacity(3); |
| 1022 | dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); | 1022 | |
| 1023 | // TODO this will go away once we pull DWARF into a cross-platform module. | ||
| 1024 | if (emit.bin_file.cast(link.File.MachO)) |_| { | ||
| 1025 | dbg_out.dbg_info.appendAssumeCapacity(link.File.MachO.DebugSymbols.abbrev_parameter); | ||
| 1026 | } else if (emit.bin_file.cast(link.File.Elf)) |_| { | ||
| 1027 | dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); | ||
| 1028 | } else return emit.fail("TODO DWARF in non-MachO and non-ELF backend", .{}); | ||
| 1029 | |||
| 1023 | dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 1030 | dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 1024 | 1, // ULEB128 dwarf expression length | 1031 | 1, // ULEB128 dwarf expression length |
| 1025 | reg.dwarfLocOp(), | 1032 | reg.dwarfLocOp(), |
| ... | @@ -1042,7 +1049,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32 | ... | @@ -1042,7 +1049,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32 |
| 1042 | // for example when -fomit-frame-pointer is set. | 1049 | // for example when -fomit-frame-pointer is set. |
| 1043 | const disp = @intCast(i32, max_stack) - off + 16; | 1050 | const disp = @intCast(i32, max_stack) - off + 16; |
| 1044 | try dbg_out.dbg_info.ensureUnusedCapacity(8); | 1051 | try dbg_out.dbg_info.ensureUnusedCapacity(8); |
| 1045 | dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); | 1052 | |
| 1053 | // TODO this will go away once we pull DWARF into a cross-platform module. | ||
| 1054 | if (emit.bin_file.cast(link.File.MachO)) |_| { | ||
| 1055 | dbg_out.dbg_info.appendAssumeCapacity(link.File.MachO.DebugSymbols.abbrev_parameter); | ||
| 1056 | } else if (emit.bin_file.cast(link.File.Elf)) |_| { | ||
| 1057 | dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); | ||
| 1058 | } else return emit.fail("TODO DWARF in non-MachO and non-ELF backend", .{}); | ||
| 1059 | |||
| 1046 | const fixup = dbg_out.dbg_info.items.len; | 1060 | const fixup = dbg_out.dbg_info.items.len; |
| 1047 | dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 1061 | dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 1048 | 1, // we will backpatch it after we encode the displacement in LEB128 | 1062 | 1, // we will backpatch it after we encode the displacement in LEB128 |
src/codegen.zig-1| ... | @@ -639,7 +639,6 @@ pub fn generateSymbol( | ... | @@ -639,7 +639,6 @@ pub fn generateSymbol( |
| 639 | return Result{ .appended = {} }; | 639 | return Result{ .appended = {} }; |
| 640 | }, | 640 | }, |
| 641 | .Optional => { | 641 | .Optional => { |
| 642 | // TODO generate debug info for optionals | ||
| 643 | var opt_buf: Type.Payload.ElemType = undefined; | 642 | var opt_buf: Type.Payload.ElemType = undefined; |
| 644 | const payload_type = typed_value.ty.optionalChild(&opt_buf); | 643 | const payload_type = typed_value.ty.optionalChild(&opt_buf); |
| 645 | const is_pl = !typed_value.val.isNull(); | 644 | const is_pl = !typed_value.val.isNull(); |
src/link/Elf.zig+56-23| ... | @@ -983,10 +983,9 @@ pub const abbrev_subprogram_retvoid = 3; | ... | @@ -983,10 +983,9 @@ pub const abbrev_subprogram_retvoid = 3; |
| 983 | pub const abbrev_base_type = 4; | 983 | pub const abbrev_base_type = 4; |
| 984 | pub const abbrev_ptr_type = 5; | 984 | pub const abbrev_ptr_type = 5; |
| 985 | pub const abbrev_struct_type = 6; | 985 | pub const abbrev_struct_type = 6; |
| 986 | pub const abbrev_anon_struct_type = 7; | 986 | pub const abbrev_struct_member = 7; |
| 987 | pub const abbrev_struct_member = 8; | 987 | pub const abbrev_pad1 = 8; |
| 988 | pub const abbrev_pad1 = 9; | 988 | pub const abbrev_parameter = 9; |
| 989 | pub const abbrev_parameter = 10; | ||
| 990 | 989 | ||
| 991 | pub fn flush(self: *Elf, comp: *Compilation) !void { | 990 | pub fn flush(self: *Elf, comp: *Compilation) !void { |
| 992 | if (self.base.options.emit == null) { | 991 | if (self.base.options.emit == null) { |
| ... | @@ -1127,13 +1126,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -1127,13 +1126,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 1127 | DW.FORM.string, | 1126 | DW.FORM.string, |
| 1128 | 0, | 1127 | 0, |
| 1129 | 0, // table sentinel | 1128 | 0, // table sentinel |
| 1130 | abbrev_anon_struct_type, | ||
| 1131 | DW.TAG.structure_type, | ||
| 1132 | DW.CHILDREN.yes, // header | ||
| 1133 | DW.AT.byte_size, | ||
| 1134 | DW.FORM.sdata, | ||
| 1135 | 0, | ||
| 1136 | 0, // table sentinel | ||
| 1137 | abbrev_struct_member, | 1129 | abbrev_struct_member, |
| 1138 | DW.TAG.member, | 1130 | DW.TAG.member, |
| 1139 | DW.CHILDREN.no, // header | 1131 | DW.CHILDREN.no, // header |
| ... | @@ -3186,6 +3178,7 @@ fn addDbgInfoType( | ... | @@ -3186,6 +3178,7 @@ fn addDbgInfoType( |
| 3186 | dbg_info_buffer: *std.ArrayList(u8), | 3178 | dbg_info_buffer: *std.ArrayList(u8), |
| 3187 | dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable, | 3179 | dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable, |
| 3188 | ) error{OutOfMemory}!void { | 3180 | ) error{OutOfMemory}!void { |
| 3181 | const target = self.base.options.target; | ||
| 3189 | var relocs = std.ArrayList(struct { ty: Type, reloc: u32 }).init(arena); | 3182 | var relocs = std.ArrayList(struct { ty: Type, reloc: u32 }).init(arena); |
| 3190 | 3183 | ||
| 3191 | switch (ty.zigTypeTag()) { | 3184 | switch (ty.zigTypeTag()) { |
| ... | @@ -3202,7 +3195,7 @@ fn addDbgInfoType( | ... | @@ -3202,7 +3195,7 @@ fn addDbgInfoType( |
| 3202 | }); | 3195 | }); |
| 3203 | }, | 3196 | }, |
| 3204 | .Int => { | 3197 | .Int => { |
| 3205 | const info = ty.intInfo(self.base.options.target); | 3198 | const info = ty.intInfo(target); |
| 3206 | try dbg_info_buffer.ensureUnusedCapacity(12); | 3199 | try dbg_info_buffer.ensureUnusedCapacity(12); |
| 3207 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); | 3200 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); |
| 3208 | // DW.AT.encoding, DW.FORM.data1 | 3201 | // DW.AT.encoding, DW.FORM.data1 |
| ... | @@ -3211,7 +3204,7 @@ fn addDbgInfoType( | ... | @@ -3211,7 +3204,7 @@ fn addDbgInfoType( |
| 3211 | .unsigned => DW.ATE.unsigned, | 3204 | .unsigned => DW.ATE.unsigned, |
| 3212 | }); | 3205 | }); |
| 3213 | // DW.AT.byte_size, DW.FORM.data1 | 3206 | // DW.AT.byte_size, DW.FORM.data1 |
| 3214 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); | 3207 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target))); |
| 3215 | // DW.AT.name, DW.FORM.string | 3208 | // DW.AT.name, DW.FORM.string |
| 3216 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | 3209 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); |
| 3217 | }, | 3210 | }, |
| ... | @@ -3222,23 +3215,61 @@ fn addDbgInfoType( | ... | @@ -3222,23 +3215,61 @@ fn addDbgInfoType( |
| 3222 | // DW.AT.encoding, DW.FORM.data1 | 3215 | // DW.AT.encoding, DW.FORM.data1 |
| 3223 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.address); | 3216 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.address); |
| 3224 | // DW.AT.byte_size, DW.FORM.data1 | 3217 | // DW.AT.byte_size, DW.FORM.data1 |
| 3225 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); | 3218 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target))); |
| 3226 | // DW.AT.name, DW.FORM.string | 3219 | // DW.AT.name, DW.FORM.string |
| 3227 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | 3220 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); |
| 3228 | } else { | 3221 | } else { |
| 3229 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); | 3222 | // Non-pointer optionals are structs: struct { .maybe = *, .val = * } |
| 3230 | try dbg_info_buffer.append(abbrev_pad1); | 3223 | var buf = try arena.create(Type.Payload.ElemType); |
| 3224 | const payload_ty = ty.optionalChild(buf); | ||
| 3225 | // DW.AT.structure_type | ||
| 3226 | try dbg_info_buffer.append(abbrev_struct_type); | ||
| 3227 | // DW.AT.byte_size, DW.FORM.sdata | ||
| 3228 | const abi_size = ty.abiSize(target); | ||
| 3229 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | ||
| 3230 | // DW.AT.name, DW.FORM.string | ||
| 3231 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | ||
| 3232 | // DW.AT.member | ||
| 3233 | try dbg_info_buffer.ensureUnusedCapacity(7); | ||
| 3234 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | ||
| 3235 | // DW.AT.name, DW.FORM.string | ||
| 3236 | dbg_info_buffer.appendSliceAssumeCapacity("maybe"); | ||
| 3237 | dbg_info_buffer.appendAssumeCapacity(0); | ||
| 3238 | // DW.AT.type, DW.FORM.ref4 | ||
| 3239 | var index = dbg_info_buffer.items.len; | ||
| 3240 | try dbg_info_buffer.resize(index + 4); | ||
| 3241 | try relocs.append(.{ .ty = Type.bool, .reloc = @intCast(u32, index) }); | ||
| 3242 | // DW.AT.data_member_location, DW.FORM.sdata | ||
| 3243 | try dbg_info_buffer.ensureUnusedCapacity(6); | ||
| 3244 | dbg_info_buffer.appendAssumeCapacity(0); | ||
| 3245 | // DW.AT.member | ||
| 3246 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | ||
| 3247 | // DW.AT.name, DW.FORM.string | ||
| 3248 | dbg_info_buffer.appendSliceAssumeCapacity("val"); | ||
| 3249 | dbg_info_buffer.appendAssumeCapacity(0); | ||
| 3250 | // DW.AT.type, DW.FORM.ref4 | ||
| 3251 | index = dbg_info_buffer.items.len; | ||
| 3252 | try dbg_info_buffer.resize(index + 4); | ||
| 3253 | try relocs.append(.{ .ty = payload_ty, .reloc = @intCast(u32, index) }); | ||
| 3254 | // DW.AT.data_member_location, DW.FORM.sdata | ||
| 3255 | const offset = abi_size - payload_ty.abiSize(target); | ||
| 3256 | try leb128.writeULEB128(dbg_info_buffer.writer(), offset); | ||
| 3257 | // DW.AT.structure_type delimit children | ||
| 3258 | try dbg_info_buffer.append(0); | ||
| 3231 | } | 3259 | } |
| 3232 | }, | 3260 | }, |
| 3233 | .Pointer => { | 3261 | .Pointer => { |
| 3234 | if (ty.isSlice()) { | 3262 | if (ty.isSlice()) { |
| 3235 | // Slices are anonymous structs: struct { .ptr = *, .len = N } | 3263 | // Slices are structs: struct { .ptr = *, .len = N } |
| 3236 | try dbg_info_buffer.ensureUnusedCapacity(23); | ||
| 3237 | // DW.AT.structure_type | 3264 | // DW.AT.structure_type |
| 3238 | dbg_info_buffer.appendAssumeCapacity(abbrev_anon_struct_type); | 3265 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 3266 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_type); | ||
| 3239 | // DW.AT.byte_size, DW.FORM.sdata | 3267 | // DW.AT.byte_size, DW.FORM.sdata |
| 3240 | dbg_info_buffer.appendAssumeCapacity(16); | 3268 | dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2); |
| 3269 | // DW.AT.name, DW.FORM.string | ||
| 3270 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | ||
| 3241 | // DW.AT.member | 3271 | // DW.AT.member |
| 3272 | try dbg_info_buffer.ensureUnusedCapacity(5); | ||
| 3242 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | 3273 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); |
| 3243 | // DW.AT.name, DW.FORM.string | 3274 | // DW.AT.name, DW.FORM.string |
| 3244 | dbg_info_buffer.appendSliceAssumeCapacity("ptr"); | 3275 | dbg_info_buffer.appendSliceAssumeCapacity("ptr"); |
| ... | @@ -3250,6 +3281,7 @@ fn addDbgInfoType( | ... | @@ -3250,6 +3281,7 @@ fn addDbgInfoType( |
| 3250 | const ptr_ty = ty.slicePtrFieldType(buf); | 3281 | const ptr_ty = ty.slicePtrFieldType(buf); |
| 3251 | try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) }); | 3282 | try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) }); |
| 3252 | // DW.AT.data_member_location, DW.FORM.sdata | 3283 | // DW.AT.data_member_location, DW.FORM.sdata |
| 3284 | try dbg_info_buffer.ensureUnusedCapacity(6); | ||
| 3253 | dbg_info_buffer.appendAssumeCapacity(0); | 3285 | dbg_info_buffer.appendAssumeCapacity(0); |
| 3254 | // DW.AT.member | 3286 | // DW.AT.member |
| 3255 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | 3287 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); |
| ... | @@ -3261,7 +3293,8 @@ fn addDbgInfoType( | ... | @@ -3261,7 +3293,8 @@ fn addDbgInfoType( |
| 3261 | try dbg_info_buffer.resize(index + 4); | 3293 | try dbg_info_buffer.resize(index + 4); |
| 3262 | try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) }); | 3294 | try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) }); |
| 3263 | // DW.AT.data_member_location, DW.FORM.sdata | 3295 | // DW.AT.data_member_location, DW.FORM.sdata |
| 3264 | dbg_info_buffer.appendAssumeCapacity(8); | 3296 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 3297 | dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize)); | ||
| 3265 | // DW.AT.structure_type delimit children | 3298 | // DW.AT.structure_type delimit children |
| 3266 | dbg_info_buffer.appendAssumeCapacity(0); | 3299 | dbg_info_buffer.appendAssumeCapacity(0); |
| 3267 | } else { | 3300 | } else { |
| ... | @@ -3278,7 +3311,7 @@ fn addDbgInfoType( | ... | @@ -3278,7 +3311,7 @@ fn addDbgInfoType( |
| 3278 | // DW.AT.structure_type | 3311 | // DW.AT.structure_type |
| 3279 | try dbg_info_buffer.append(abbrev_struct_type); | 3312 | try dbg_info_buffer.append(abbrev_struct_type); |
| 3280 | // DW.AT.byte_size, DW.FORM.sdata | 3313 | // DW.AT.byte_size, DW.FORM.sdata |
| 3281 | const abi_size = ty.abiSize(self.base.options.target); | 3314 | const abi_size = ty.abiSize(target); |
| 3282 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | 3315 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); |
| 3283 | // DW.AT.name, DW.FORM.string | 3316 | // DW.AT.name, DW.FORM.string |
| 3284 | const struct_name = try ty.nameAlloc(arena); | 3317 | const struct_name = try ty.nameAlloc(arena); |
| ... | @@ -3306,7 +3339,7 @@ fn addDbgInfoType( | ... | @@ -3306,7 +3339,7 @@ fn addDbgInfoType( |
| 3306 | try dbg_info_buffer.resize(index + 4); | 3339 | try dbg_info_buffer.resize(index + 4); |
| 3307 | try relocs.append(.{ .ty = field.ty, .reloc = @intCast(u32, index) }); | 3340 | try relocs.append(.{ .ty = field.ty, .reloc = @intCast(u32, index) }); |
| 3308 | // DW.AT.data_member_location, DW.FORM.sdata | 3341 | // DW.AT.data_member_location, DW.FORM.sdata |
| 3309 | const field_off = ty.structFieldOffset(field_index, self.base.options.target); | 3342 | const field_off = ty.structFieldOffset(field_index, target); |
| 3310 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); | 3343 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); |
| 3311 | } | 3344 | } |
| 3312 | 3345 |
src/link/MachO.zig+30-6| ... | @@ -27,7 +27,6 @@ const Atom = @import("MachO/Atom.zig"); | ... | @@ -27,7 +27,6 @@ const Atom = @import("MachO/Atom.zig"); |
| 27 | const Cache = @import("../Cache.zig"); | 27 | const Cache = @import("../Cache.zig"); |
| 28 | const CodeSignature = @import("MachO/CodeSignature.zig"); | 28 | const CodeSignature = @import("MachO/CodeSignature.zig"); |
| 29 | const Compilation = @import("../Compilation.zig"); | 29 | const Compilation = @import("../Compilation.zig"); |
| 30 | const DebugSymbols = @import("MachO/DebugSymbols.zig"); | ||
| 31 | const Dylib = @import("MachO/Dylib.zig"); | 30 | const Dylib = @import("MachO/Dylib.zig"); |
| 32 | const File = link.File; | 31 | const File = link.File; |
| 33 | const Object = @import("MachO/Object.zig"); | 32 | const Object = @import("MachO/Object.zig"); |
| ... | @@ -43,6 +42,7 @@ const TypedValue = @import("../TypedValue.zig"); | ... | @@ -43,6 +42,7 @@ const TypedValue = @import("../TypedValue.zig"); |
| 43 | const Value = @import("../value.zig").Value; | 42 | const Value = @import("../value.zig").Value; |
| 44 | 43 | ||
| 45 | pub const TextBlock = Atom; | 44 | pub const TextBlock = Atom; |
| 45 | pub const DebugSymbols = @import("MachO/DebugSymbols.zig"); | ||
| 46 | 46 | ||
| 47 | pub const base_tag: File.Tag = File.Tag.macho; | 47 | pub const base_tag: File.Tag = File.Tag.macho; |
| 48 | 48 | ||
| ... | @@ -2178,6 +2178,34 @@ fn writeAllAtoms(self: *MachO) !void { | ... | @@ -2178,6 +2178,34 @@ fn writeAllAtoms(self: *MachO) !void { |
| 2178 | } | 2178 | } |
| 2179 | } | 2179 | } |
| 2180 | 2180 | ||
| 2181 | fn writePadding(self: *MachO, match: MatchingSection, size: usize, writer: anytype) !void { | ||
| 2182 | const is_code = match.seg == self.text_segment_cmd_index.? and match.sect == self.text_section_index.?; | ||
| 2183 | const min_alignment: u3 = if (!is_code) | ||
| 2184 | 1 | ||
| 2185 | else switch (self.base.options.target.cpu.arch) { | ||
| 2186 | .aarch64 => @sizeOf(u32), | ||
| 2187 | .x86_64 => @as(u3, 1), | ||
| 2188 | else => unreachable, | ||
| 2189 | }; | ||
| 2190 | |||
| 2191 | const len = @divExact(size, min_alignment); | ||
| 2192 | var i: usize = 0; | ||
| 2193 | while (i < len) : (i += 1) { | ||
| 2194 | if (!is_code) { | ||
| 2195 | try writer.writeByte(0); | ||
| 2196 | } else switch (self.base.options.target.cpu.arch) { | ||
| 2197 | .aarch64 => { | ||
| 2198 | const inst = aarch64.Instruction.nop(); | ||
| 2199 | try writer.writeIntLittle(u32, inst.toU32()); | ||
| 2200 | }, | ||
| 2201 | .x86_64 => { | ||
| 2202 | try writer.writeByte(0x90); | ||
| 2203 | }, | ||
| 2204 | else => unreachable, | ||
| 2205 | } | ||
| 2206 | } | ||
| 2207 | } | ||
| 2208 | |||
| 2181 | fn writeAtoms(self: *MachO) !void { | 2209 | fn writeAtoms(self: *MachO) !void { |
| 2182 | var buffer = std.ArrayList(u8).init(self.base.allocator); | 2210 | var buffer = std.ArrayList(u8).init(self.base.allocator); |
| 2183 | defer buffer.deinit(); | 2211 | defer buffer.deinit(); |
| ... | @@ -2213,11 +2241,7 @@ fn writeAtoms(self: *MachO) !void { | ... | @@ -2213,11 +2241,7 @@ fn writeAtoms(self: *MachO) !void { |
| 2213 | try atom.resolveRelocs(self); | 2241 | try atom.resolveRelocs(self); |
| 2214 | try buffer.appendSlice(atom.code.items); | 2242 | try buffer.appendSlice(atom.code.items); |
| 2215 | try buffer.ensureUnusedCapacity(padding_size); | 2243 | try buffer.ensureUnusedCapacity(padding_size); |
| 2216 | 2244 | try self.writePadding(match, padding_size, buffer.writer()); | |
| 2217 | var i: usize = 0; | ||
| 2218 | while (i < padding_size) : (i += 1) { | ||
| 2219 | buffer.appendAssumeCapacity(0); | ||
| 2220 | } | ||
| 2221 | 2245 | ||
| 2222 | if (file_offset == null) { | 2246 | if (file_offset == null) { |
| 2223 | file_offset = sect.offset + atom_sym.n_value - sect.addr; | 2247 | file_offset = sect.offset + atom_sym.n_value - sect.addr; |
src/link/MachO/DebugSymbols.zig+56-36| ... | @@ -78,16 +78,15 @@ debug_aranges_section_dirty: bool = false, | ... | @@ -78,16 +78,15 @@ debug_aranges_section_dirty: bool = false, |
| 78 | debug_info_header_dirty: bool = false, | 78 | debug_info_header_dirty: bool = false, |
| 79 | debug_line_header_dirty: bool = false, | 79 | debug_line_header_dirty: bool = false, |
| 80 | 80 | ||
| 81 | const abbrev_compile_unit = 1; | 81 | pub const abbrev_compile_unit = 1; |
| 82 | const abbrev_subprogram = 2; | 82 | pub const abbrev_subprogram = 2; |
| 83 | const abbrev_subprogram_retvoid = 3; | 83 | pub const abbrev_subprogram_retvoid = 3; |
| 84 | const abbrev_base_type = 4; | 84 | pub const abbrev_base_type = 4; |
| 85 | const abbrev_ptr_type = 5; | 85 | pub const abbrev_ptr_type = 5; |
| 86 | const abbrev_struct_type = 6; | 86 | pub const abbrev_struct_type = 6; |
| 87 | const abbrev_anon_struct_type = 7; | 87 | pub const abbrev_struct_member = 7; |
| 88 | const abbrev_struct_member = 8; | 88 | pub const abbrev_pad1 = 8; |
| 89 | const abbrev_pad1 = 9; | 89 | pub const abbrev_parameter = 9; |
| 90 | const abbrev_parameter = 10; | ||
| 91 | 90 | ||
| 92 | /// The reloc offset for the virtual address of a function in its Line Number Program. | 91 | /// The reloc offset for the virtual address of a function in its Line Number Program. |
| 93 | /// Size is a virtual address integer. | 92 | /// Size is a virtual address integer. |
| ... | @@ -353,13 +352,6 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti | ... | @@ -353,13 +352,6 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti |
| 353 | DW.FORM.string, | 352 | DW.FORM.string, |
| 354 | 0, | 353 | 0, |
| 355 | 0, // table sentinel | 354 | 0, // table sentinel |
| 356 | abbrev_anon_struct_type, | ||
| 357 | DW.TAG.structure_type, | ||
| 358 | DW.CHILDREN.yes, // header | ||
| 359 | DW.AT.byte_size, | ||
| 360 | DW.FORM.sdata, | ||
| 361 | 0, | ||
| 362 | 0, // table sentinel | ||
| 363 | abbrev_struct_member, | 355 | abbrev_struct_member, |
| 364 | DW.TAG.member, | 356 | DW.TAG.member, |
| 365 | DW.CHILDREN.no, // header | 357 | DW.CHILDREN.no, // header |
| ... | @@ -1134,18 +1126,6 @@ pub fn commitDeclDebugInfo( | ... | @@ -1134,18 +1126,6 @@ pub fn commitDeclDebugInfo( |
| 1134 | mem.writeIntLittle(u32, ptr, @intCast(u32, text_block.size)); | 1126 | mem.writeIntLittle(u32, ptr, @intCast(u32, text_block.size)); |
| 1135 | } | 1127 | } |
| 1136 | 1128 | ||
| 1137 | { | ||
| 1138 | // Advance line and PC. | ||
| 1139 | // TODO encapsulate logic in a helper function. | ||
| 1140 | try dbg_line_buffer.append(DW.LNS.advance_pc); | ||
| 1141 | try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size); | ||
| 1142 | |||
| 1143 | try dbg_line_buffer.append(DW.LNS.advance_line); | ||
| 1144 | const func = decl.val.castTag(.function).?.data; | ||
| 1145 | const line_off = @intCast(u28, func.rbrace_line - func.lbrace_line); | ||
| 1146 | try leb.writeULEB128(dbg_line_buffer.writer(), line_off); | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence }); | 1129 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence }); |
| 1150 | 1130 | ||
| 1151 | // Now we have the full contents and may allocate a region to store it. | 1131 | // Now we have the full contents and may allocate a region to store it. |
| ... | @@ -1332,19 +1312,57 @@ fn addDbgInfoType( | ... | @@ -1332,19 +1312,57 @@ fn addDbgInfoType( |
| 1332 | // DW.AT.name, DW.FORM.string | 1312 | // DW.AT.name, DW.FORM.string |
| 1333 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | 1313 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); |
| 1334 | } else { | 1314 | } else { |
| 1335 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); | 1315 | // Non-pointer optionals are structs: struct { .maybe = *, .val = * } |
| 1336 | try dbg_info_buffer.append(abbrev_pad1); | 1316 | var buf = try arena.create(Type.Payload.ElemType); |
| 1317 | const payload_ty = ty.optionalChild(buf); | ||
| 1318 | // DW.AT.structure_type | ||
| 1319 | try dbg_info_buffer.append(abbrev_struct_type); | ||
| 1320 | // DW.AT.byte_size, DW.FORM.sdata | ||
| 1321 | const abi_size = ty.abiSize(target); | ||
| 1322 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | ||
| 1323 | // DW.AT.name, DW.FORM.string | ||
| 1324 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | ||
| 1325 | // DW.AT.member | ||
| 1326 | try dbg_info_buffer.ensureUnusedCapacity(7); | ||
| 1327 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | ||
| 1328 | // DW.AT.name, DW.FORM.string | ||
| 1329 | dbg_info_buffer.appendSliceAssumeCapacity("maybe"); | ||
| 1330 | dbg_info_buffer.appendAssumeCapacity(0); | ||
| 1331 | // DW.AT.type, DW.FORM.ref4 | ||
| 1332 | var index = dbg_info_buffer.items.len; | ||
| 1333 | try dbg_info_buffer.resize(index + 4); | ||
| 1334 | try relocs.append(.{ .ty = Type.bool, .reloc = @intCast(u32, index) }); | ||
| 1335 | // DW.AT.data_member_location, DW.FORM.sdata | ||
| 1336 | try dbg_info_buffer.ensureUnusedCapacity(6); | ||
| 1337 | dbg_info_buffer.appendAssumeCapacity(0); | ||
| 1338 | // DW.AT.member | ||
| 1339 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | ||
| 1340 | // DW.AT.name, DW.FORM.string | ||
| 1341 | dbg_info_buffer.appendSliceAssumeCapacity("val"); | ||
| 1342 | dbg_info_buffer.appendAssumeCapacity(0); | ||
| 1343 | // DW.AT.type, DW.FORM.ref4 | ||
| 1344 | index = dbg_info_buffer.items.len; | ||
| 1345 | try dbg_info_buffer.resize(index + 4); | ||
| 1346 | try relocs.append(.{ .ty = payload_ty, .reloc = @intCast(u32, index) }); | ||
| 1347 | // DW.AT.data_member_location, DW.FORM.sdata | ||
| 1348 | const offset = abi_size - payload_ty.abiSize(target); | ||
| 1349 | try leb128.writeULEB128(dbg_info_buffer.writer(), offset); | ||
| 1350 | // DW.AT.structure_type delimit children | ||
| 1351 | try dbg_info_buffer.append(0); | ||
| 1337 | } | 1352 | } |
| 1338 | }, | 1353 | }, |
| 1339 | .Pointer => { | 1354 | .Pointer => { |
| 1340 | if (ty.isSlice()) { | 1355 | if (ty.isSlice()) { |
| 1341 | // Slices are anonymous structs: struct { .ptr = *, .len = N } | 1356 | // Slices are structs: struct { .ptr = *, .len = N } |
| 1342 | try dbg_info_buffer.ensureUnusedCapacity(23); | ||
| 1343 | // DW.AT.structure_type | 1357 | // DW.AT.structure_type |
| 1344 | dbg_info_buffer.appendAssumeCapacity(abbrev_anon_struct_type); | 1358 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 1359 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_type); | ||
| 1345 | // DW.AT.byte_size, DW.FORM.sdata | 1360 | // DW.AT.byte_size, DW.FORM.sdata |
| 1346 | dbg_info_buffer.appendAssumeCapacity(16); | 1361 | dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2); |
| 1362 | // DW.AT.name, DW.FORM.string | ||
| 1363 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | ||
| 1347 | // DW.AT.member | 1364 | // DW.AT.member |
| 1365 | try dbg_info_buffer.ensureUnusedCapacity(5); | ||
| 1348 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | 1366 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); |
| 1349 | // DW.AT.name, DW.FORM.string | 1367 | // DW.AT.name, DW.FORM.string |
| 1350 | dbg_info_buffer.appendSliceAssumeCapacity("ptr"); | 1368 | dbg_info_buffer.appendSliceAssumeCapacity("ptr"); |
| ... | @@ -1356,6 +1374,7 @@ fn addDbgInfoType( | ... | @@ -1356,6 +1374,7 @@ fn addDbgInfoType( |
| 1356 | const ptr_ty = ty.slicePtrFieldType(buf); | 1374 | const ptr_ty = ty.slicePtrFieldType(buf); |
| 1357 | try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) }); | 1375 | try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) }); |
| 1358 | // DW.AT.data_member_location, DW.FORM.sdata | 1376 | // DW.AT.data_member_location, DW.FORM.sdata |
| 1377 | try dbg_info_buffer.ensureUnusedCapacity(6); | ||
| 1359 | dbg_info_buffer.appendAssumeCapacity(0); | 1378 | dbg_info_buffer.appendAssumeCapacity(0); |
| 1360 | // DW.AT.member | 1379 | // DW.AT.member |
| 1361 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); | 1380 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); |
| ... | @@ -1367,7 +1386,8 @@ fn addDbgInfoType( | ... | @@ -1367,7 +1386,8 @@ fn addDbgInfoType( |
| 1367 | try dbg_info_buffer.resize(index + 4); | 1386 | try dbg_info_buffer.resize(index + 4); |
| 1368 | try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) }); | 1387 | try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) }); |
| 1369 | // DW.AT.data_member_location, DW.FORM.sdata | 1388 | // DW.AT.data_member_location, DW.FORM.sdata |
| 1370 | dbg_info_buffer.appendAssumeCapacity(8); | 1389 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 1390 | dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize)); | ||
| 1371 | // DW.AT.structure_type delimit children | 1391 | // DW.AT.structure_type delimit children |
| 1372 | dbg_info_buffer.appendAssumeCapacity(0); | 1392 | dbg_info_buffer.appendAssumeCapacity(0); |
| 1373 | } else { | 1393 | } else { |