| author | |
| committer | |
| log | 16d74809d44d6bb8db1a32923ef8db43d956e24d |
| tree | 78344089f8c4cc2bdc07ea74f0a47b8f500d2fcb |
| parent | 0a70455095a19a4c18497e6786ca6139c1cc2892 |
| parent | 55864e98e08c9d44ee2ea6fc1f3a3c2a98042310 |
| signature |
Dwarf: inline calls progress30 files changed, 1236 insertions(+), 698 deletions(-)
src/Air.zig+14-11| ... | @@ -456,6 +456,8 @@ pub const Inst = struct { | ... | @@ -456,6 +456,8 @@ pub const Inst = struct { |
| 456 | /// Same as `dbg_var_ptr` except the local is a const, not a var, and the | 456 | /// Same as `dbg_var_ptr` except the local is a const, not a var, and the |
| 457 | /// operand is the local's value. | 457 | /// operand is the local's value. |
| 458 | dbg_var_val, | 458 | dbg_var_val, |
| 459 | /// Same as `dbg_var_val` except the local is an inline function argument. | ||
| 460 | dbg_arg_inline, | ||
| 459 | /// ?T => bool | 461 | /// ?T => bool |
| 460 | /// Result type is always bool. | 462 | /// Result type is always bool. |
| 461 | /// Uses the `un_op` field. | 463 | /// Uses the `un_op` field. |
| ... | @@ -1022,10 +1024,7 @@ pub const Inst = struct { | ... | @@ -1022,10 +1024,7 @@ pub const Inst = struct { |
| 1022 | ty: Ref, | 1024 | ty: Ref, |
| 1023 | /// Index into `extra` of a null-terminated string representing the parameter name. | 1025 | /// Index into `extra` of a null-terminated string representing the parameter name. |
| 1024 | /// This is `.none` if debug info is stripped. | 1026 | /// This is `.none` if debug info is stripped. |
| 1025 | name: enum(u32) { | 1027 | name: NullTerminatedString, |
| 1026 | none = std.math.maxInt(u32), | ||
| 1027 | _, | ||
| 1028 | }, | ||
| 1029 | }, | 1028 | }, |
| 1030 | ty_op: struct { | 1029 | ty_op: struct { |
| 1031 | ty: Ref, | 1030 | ty: Ref, |
| ... | @@ -1440,6 +1439,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1440,6 +1439,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1440 | .dbg_stmt, | 1439 | .dbg_stmt, |
| 1441 | .dbg_var_ptr, | 1440 | .dbg_var_ptr, |
| 1442 | .dbg_var_val, | 1441 | .dbg_var_val, |
| 1442 | .dbg_arg_inline, | ||
| 1443 | .store, | 1443 | .store, |
| 1444 | .store_safe, | 1444 | .store_safe, |
| 1445 | .fence, | 1445 | .fence, |
| ... | @@ -1562,14 +1562,16 @@ pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value { | ... | @@ -1562,14 +1562,16 @@ pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value { |
| 1562 | return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt); | 1562 | return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt); |
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 { | 1565 | pub const NullTerminatedString = enum(u32) { |
| 1566 | const bytes = std.mem.sliceAsBytes(air.extra[index..]); | 1566 | none = std.math.maxInt(u32), |
| 1567 | var end: usize = 0; | 1567 | _, |
| 1568 | while (bytes[end] != 0) { | 1568 | |
| 1569 | end += 1; | 1569 | pub fn toSlice(nts: NullTerminatedString, air: Air) [:0]const u8 { |
| 1570 | if (nts == .none) return ""; | ||
| 1571 | const bytes = std.mem.sliceAsBytes(air.extra[@intFromEnum(nts)..]); | ||
| 1572 | return bytes[0..std.mem.indexOfScalar(u8, bytes, 0).? :0]; | ||
| 1570 | } | 1573 | } |
| 1571 | return bytes[0..end :0]; | 1574 | }; |
| 1572 | } | ||
| 1573 | 1575 | ||
| 1574 | /// Returns whether the given instruction must always be lowered, for instance | 1576 | /// Returns whether the given instruction must always be lowered, for instance |
| 1575 | /// because it can cause side effects. If an instruction does not need to be | 1577 | /// because it can cause side effects. If an instruction does not need to be |
| ... | @@ -1596,6 +1598,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { | ... | @@ -1596,6 +1598,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1596 | .dbg_inline_block, | 1598 | .dbg_inline_block, |
| 1597 | .dbg_var_ptr, | 1599 | .dbg_var_ptr, |
| 1598 | .dbg_var_val, | 1600 | .dbg_var_val, |
| 1601 | .dbg_arg_inline, | ||
| 1599 | .ret, | 1602 | .ret, |
| 1600 | .ret_safe, | 1603 | .ret_safe, |
| 1601 | .ret_load, | 1604 | .ret_load, |
src/Air/types_resolved.zig+1| ... | @@ -339,6 +339,7 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool { | ... | @@ -339,6 +339,7 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool { |
| 339 | 339 | ||
| 340 | .dbg_var_ptr, | 340 | .dbg_var_ptr, |
| 341 | .dbg_var_val, | 341 | .dbg_var_val, |
| 342 | .dbg_arg_inline, | ||
| 342 | => { | 343 | => { |
| 343 | if (!checkRef(data.pl_op.operand, zcu)) return false; | 344 | if (!checkRef(data.pl_op.operand, zcu)) return false; |
| 344 | }, | 345 | }, |
src/Compilation.zig+20-8| ... | @@ -2997,14 +2997,26 @@ pub fn saveState(comp: *Compilation) !void { | ... | @@ -2997,14 +2997,26 @@ pub fn saveState(comp: *Compilation) !void { |
| 2997 | addBuf(&bufs, mem.sliceAsBytes(ip.free_dep_entries.items)); | 2997 | addBuf(&bufs, mem.sliceAsBytes(ip.free_dep_entries.items)); |
| 2998 | 2998 | ||
| 2999 | for (ip.locals, pt_headers.items) |*local, pt_header| { | 2999 | for (ip.locals, pt_headers.items) |*local, pt_header| { |
| 3000 | addBuf(&bufs, mem.sliceAsBytes(local.shared.limbs.view().items(.@"0")[0..pt_header.intern_pool.limbs_len])); | 3000 | if (pt_header.intern_pool.limbs_len > 0) { |
| 3001 | addBuf(&bufs, mem.sliceAsBytes(local.shared.extra.view().items(.@"0")[0..pt_header.intern_pool.extra_len])); | 3001 | addBuf(&bufs, mem.sliceAsBytes(local.shared.limbs.view().items(.@"0")[0..pt_header.intern_pool.limbs_len])); |
| 3002 | addBuf(&bufs, mem.sliceAsBytes(local.shared.items.view().items(.data)[0..pt_header.intern_pool.items_len])); | 3002 | } |
| 3003 | addBuf(&bufs, mem.sliceAsBytes(local.shared.items.view().items(.tag)[0..pt_header.intern_pool.items_len])); | 3003 | if (pt_header.intern_pool.extra_len > 0) { |
| 3004 | addBuf(&bufs, local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]); | 3004 | addBuf(&bufs, mem.sliceAsBytes(local.shared.extra.view().items(.@"0")[0..pt_header.intern_pool.extra_len])); |
| 3005 | addBuf(&bufs, mem.sliceAsBytes(local.shared.tracked_insts.view().items(.@"0")[0..pt_header.intern_pool.tracked_insts_len])); | 3005 | } |
| 3006 | addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.bin_digest)[0..pt_header.intern_pool.files_len])); | 3006 | if (pt_header.intern_pool.items_len > 0) { |
| 3007 | addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.root_type)[0..pt_header.intern_pool.files_len])); | 3007 | addBuf(&bufs, mem.sliceAsBytes(local.shared.items.view().items(.data)[0..pt_header.intern_pool.items_len])); |
| 3008 | addBuf(&bufs, mem.sliceAsBytes(local.shared.items.view().items(.tag)[0..pt_header.intern_pool.items_len])); | ||
| 3009 | } | ||
| 3010 | if (pt_header.intern_pool.string_bytes_len > 0) { | ||
| 3011 | addBuf(&bufs, local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]); | ||
| 3012 | } | ||
| 3013 | if (pt_header.intern_pool.tracked_insts_len > 0) { | ||
| 3014 | addBuf(&bufs, mem.sliceAsBytes(local.shared.tracked_insts.view().items(.@"0")[0..pt_header.intern_pool.tracked_insts_len])); | ||
| 3015 | } | ||
| 3016 | if (pt_header.intern_pool.files_len > 0) { | ||
| 3017 | addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.bin_digest)[0..pt_header.intern_pool.files_len])); | ||
| 3018 | addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.root_type)[0..pt_header.intern_pool.files_len])); | ||
| 3019 | } | ||
| 3008 | } | 3020 | } |
| 3009 | 3021 | ||
| 3010 | //// TODO: compilation errors | 3022 | //// TODO: compilation errors |
src/Liveness.zig+2| ... | @@ -464,6 +464,7 @@ pub fn categorizeOperand( | ... | @@ -464,6 +464,7 @@ pub fn categorizeOperand( |
| 464 | 464 | ||
| 465 | .dbg_var_ptr, | 465 | .dbg_var_ptr, |
| 466 | .dbg_var_val, | 466 | .dbg_var_val, |
| 467 | .dbg_arg_inline, | ||
| 467 | => { | 468 | => { |
| 468 | const o = air_datas[@intFromEnum(inst)].pl_op.operand; | 469 | const o = air_datas[@intFromEnum(inst)].pl_op.operand; |
| 469 | if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); | 470 | if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); |
| ... | @@ -1097,6 +1098,7 @@ fn analyzeInst( | ... | @@ -1097,6 +1098,7 @@ fn analyzeInst( |
| 1097 | 1098 | ||
| 1098 | .dbg_var_ptr, | 1099 | .dbg_var_ptr, |
| 1099 | .dbg_var_val, | 1100 | .dbg_var_val, |
| 1101 | .dbg_arg_inline, | ||
| 1100 | => { | 1102 | => { |
| 1101 | const operand = inst_datas[@intFromEnum(inst)].pl_op.operand; | 1103 | const operand = inst_datas[@intFromEnum(inst)].pl_op.operand; |
| 1102 | return analyzeOperands(a, pass, data, inst, .{ operand, .none, .none }); | 1104 | return analyzeOperands(a, pass, data, inst, .{ operand, .none, .none }); |
src/Liveness/Verify.zig+1| ... | @@ -157,6 +157,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -157,6 +157,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 157 | }, | 157 | }, |
| 158 | .dbg_var_ptr, | 158 | .dbg_var_ptr, |
| 159 | .dbg_var_val, | 159 | .dbg_var_val, |
| 160 | .dbg_arg_inline, | ||
| 160 | .wasm_memory_grow, | 161 | .wasm_memory_grow, |
| 161 | => { | 162 | => { |
| 162 | const pl_op = data[@intFromEnum(inst)].pl_op; | 163 | const pl_op = data[@intFromEnum(inst)].pl_op; |
src/Sema.zig+11-10| ... | @@ -376,7 +376,7 @@ pub const Block = struct { | ... | @@ -376,7 +376,7 @@ pub const Block = struct { |
| 376 | 376 | ||
| 377 | c_import_buf: ?*std.ArrayList(u8) = null, | 377 | c_import_buf: ?*std.ArrayList(u8) = null, |
| 378 | 378 | ||
| 379 | /// If not `null`, this boolean is set when a `dbg_var_ptr` or `dbg_var_val` | 379 | /// If not `null`, this boolean is set when a `dbg_var_ptr`, `dbg_var_val`, or `dbg_arg_inline`. |
| 380 | /// instruction is emitted. It signals that the innermost lexically | 380 | /// instruction is emitted. It signals that the innermost lexically |
| 381 | /// enclosing `block`/`block_inline` should be translated into a real AIR | 381 | /// enclosing `block`/`block_inline` should be translated into a real AIR |
| 382 | /// `block` in order for codegen to match lexical scoping for debug vars. | 382 | /// `block` in order for codegen to match lexical scoping for debug vars. |
| ... | @@ -6567,7 +6567,7 @@ fn addDbgVar( | ... | @@ -6567,7 +6567,7 @@ fn addDbgVar( |
| 6567 | const operand_ty = sema.typeOf(operand); | 6567 | const operand_ty = sema.typeOf(operand); |
| 6568 | const val_ty = switch (air_tag) { | 6568 | const val_ty = switch (air_tag) { |
| 6569 | .dbg_var_ptr => operand_ty.childType(mod), | 6569 | .dbg_var_ptr => operand_ty.childType(mod), |
| 6570 | .dbg_var_val => operand_ty, | 6570 | .dbg_var_val, .dbg_arg_inline => operand_ty, |
| 6571 | else => unreachable, | 6571 | else => unreachable, |
| 6572 | }; | 6572 | }; |
| 6573 | if (try sema.typeRequiresComptime(val_ty)) return; | 6573 | if (try sema.typeRequiresComptime(val_ty)) return; |
| ... | @@ -6586,25 +6586,26 @@ fn addDbgVar( | ... | @@ -6586,25 +6586,26 @@ fn addDbgVar( |
| 6586 | if (block.need_debug_scope) |ptr| ptr.* = true; | 6586 | if (block.need_debug_scope) |ptr| ptr.* = true; |
| 6587 | 6587 | ||
| 6588 | // Add the name to the AIR. | 6588 | // Add the name to the AIR. |
| 6589 | const name_extra_index = try sema.appendAirString(name); | 6589 | const name_nts = try sema.appendAirString(name); |
| 6590 | 6590 | ||
| 6591 | _ = try block.addInst(.{ | 6591 | _ = try block.addInst(.{ |
| 6592 | .tag = air_tag, | 6592 | .tag = air_tag, |
| 6593 | .data = .{ .pl_op = .{ | 6593 | .data = .{ .pl_op = .{ |
| 6594 | .payload = name_extra_index, | 6594 | .payload = @intFromEnum(name_nts), |
| 6595 | .operand = operand, | 6595 | .operand = operand, |
| 6596 | } }, | 6596 | } }, |
| 6597 | }); | 6597 | }); |
| 6598 | } | 6598 | } |
| 6599 | 6599 | ||
| 6600 | pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!u32 { | 6600 | pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!Air.NullTerminatedString { |
| 6601 | const str_extra_index: u32 = @intCast(sema.air_extra.items.len); | 6601 | if (str.len == 0) return .none; |
| 6602 | const nts: Air.NullTerminatedString = @enumFromInt(sema.air_extra.items.len); | ||
| 6602 | const elements_used = str.len / 4 + 1; | 6603 | const elements_used = str.len / 4 + 1; |
| 6603 | const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used); | 6604 | const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used); |
| 6604 | const buffer = mem.sliceAsBytes(elements); | 6605 | const buffer = mem.sliceAsBytes(elements); |
| 6605 | @memcpy(buffer[0..str.len], str); | 6606 | @memcpy(buffer[0..str.len], str); |
| 6606 | buffer[str.len] = 0; | 6607 | buffer[str.len] = 0; |
| 6607 | return str_extra_index; | 6608 | return nts; |
| 6608 | } | 6609 | } |
| 6609 | 6610 | ||
| 6610 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6611 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -7748,14 +7749,14 @@ fn analyzeCall( | ... | @@ -7748,14 +7749,14 @@ fn analyzeCall( |
| 7748 | const param_name = sema.code.nullTerminatedString(extra.data.name); | 7749 | const param_name = sema.code.nullTerminatedString(extra.data.name); |
| 7749 | const inst = sema.inst_map.get(param).?; | 7750 | const inst = sema.inst_map.get(param).?; |
| 7750 | 7751 | ||
| 7751 | try sema.addDbgVar(&child_block, inst, .dbg_var_val, param_name); | 7752 | try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name); |
| 7752 | }, | 7753 | }, |
| 7753 | .param_anytype, .param_anytype_comptime => { | 7754 | .param_anytype, .param_anytype_comptime => { |
| 7754 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].str_tok; | 7755 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].str_tok; |
| 7755 | const param_name = inst_data.get(sema.code); | 7756 | const param_name = inst_data.get(sema.code); |
| 7756 | const inst = sema.inst_map.get(param).?; | 7757 | const inst = sema.inst_map.get(param).?; |
| 7757 | 7758 | ||
| 7758 | try sema.addDbgVar(&child_block, inst, .dbg_var_val, param_name); | 7759 | try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name); |
| 7759 | }, | 7760 | }, |
| 7760 | else => continue, | 7761 | else => continue, |
| 7761 | }; | 7762 | }; |
| ... | @@ -8266,7 +8267,7 @@ fn instantiateGenericCall( | ... | @@ -8266,7 +8267,7 @@ fn instantiateGenericCall( |
| 8266 | .name = if (child_block.ownerModule().strip) | 8267 | .name = if (child_block.ownerModule().strip) |
| 8267 | .none | 8268 | .none |
| 8268 | else | 8269 | else |
| 8269 | @enumFromInt(try sema.appendAirString(fn_zir.nullTerminatedString(param_name))), | 8270 | try sema.appendAirString(fn_zir.nullTerminatedString(param_name)), |
| 8270 | } }, | 8271 | } }, |
| 8271 | })); | 8272 | })); |
| 8272 | try child_block.params.append(sema.arena, .{ | 8273 | try child_block.params.append(sema.arena, .{ |
src/Zcu/PerThread.zig+15-13| ... | @@ -1240,11 +1240,11 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { | ... | @@ -1240,11 +1240,11 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { |
| 1240 | }; | 1240 | }; |
| 1241 | } | 1241 | } |
| 1242 | 1242 | ||
| 1243 | const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) { | 1243 | const nav_already_populated, const queue_linker_work, const resolve_type = switch (ip.indexToKey(decl_val.toIntern())) { |
| 1244 | .func => |f| .{ f.owner_nav == nav_index, false }, | 1244 | .func => |f| .{ f.owner_nav == nav_index, true, false }, |
| 1245 | .variable => |v| .{ false, v.owner_nav == nav_index }, | 1245 | .variable => |v| .{ false, v.owner_nav == nav_index, true }, |
| 1246 | .@"extern" => .{ false, false }, | 1246 | .@"extern" => .{ false, false, false }, |
| 1247 | else => .{ false, true }, | 1247 | else => .{ false, true, true }, |
| 1248 | }; | 1248 | }; |
| 1249 | 1249 | ||
| 1250 | if (nav_already_populated) { | 1250 | if (nav_already_populated) { |
| ... | @@ -1317,14 +1317,16 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { | ... | @@ -1317,14 +1317,16 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { |
| 1317 | queue_codegen: { | 1317 | queue_codegen: { |
| 1318 | if (!queue_linker_work) break :queue_codegen; | 1318 | if (!queue_linker_work) break :queue_codegen; |
| 1319 | 1319 | ||
| 1320 | // Needed for codegen_nav which will call updateDecl and then the | 1320 | if (resolve_type) { |
| 1321 | // codegen backend wants full access to the Decl Type. | 1321 | // Needed for codegen_nav which will call updateDecl and then the |
| 1322 | // We also need this for the `isFnOrHasRuntimeBits` check below. | 1322 | // codegen backend wants full access to the Decl Type. |
| 1323 | // TODO: we could make the language more lenient by deferring this work | 1323 | // We also need this for the `isFnOrHasRuntimeBits` check below. |
| 1324 | // to the `codegen_nav` job. | 1324 | // TODO: we could make the language more lenient by deferring this work |
| 1325 | try decl_ty.resolveFully(pt); | 1325 | // to the `codegen_nav` job. |
| 1326 | try decl_ty.resolveFully(pt); | ||
| 1327 | } | ||
| 1326 | 1328 | ||
| 1327 | if (!decl_ty.isFnOrHasRuntimeBits(pt)) { | 1329 | if (!resolve_type or !decl_ty.hasRuntimeBits(pt)) { |
| 1328 | if (zcu.comp.config.use_llvm) break :queue_codegen; | 1330 | if (zcu.comp.config.use_llvm) break :queue_codegen; |
| 1329 | if (file.mod.strip) break :queue_codegen; | 1331 | if (file.mod.strip) break :queue_codegen; |
| 1330 | } | 1332 | } |
| ... | @@ -2158,7 +2160,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError! | ... | @@ -2158,7 +2160,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError! |
| 2158 | .name = if (inner_block.ownerModule().strip) | 2160 | .name = if (inner_block.ownerModule().strip) |
| 2159 | .none | 2161 | .none |
| 2160 | else | 2162 | else |
| 2161 | @enumFromInt(try sema.appendAirString(sema.code.nullTerminatedString(param_name))), | 2163 | try sema.appendAirString(sema.code.nullTerminatedString(param_name)), |
| 2162 | } }, | 2164 | } }, |
| 2163 | }); | 2165 | }); |
| 2164 | } | 2166 | } |
src/arch/aarch64/CodeGen.zig+15-16| ... | @@ -170,7 +170,9 @@ const DbgInfoReloc = struct { | ... | @@ -170,7 +170,9 @@ const DbgInfoReloc = struct { |
| 170 | 170 | ||
| 171 | fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void { | 171 | fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void { |
| 172 | switch (reloc.tag) { | 172 | switch (reloc.tag) { |
| 173 | .arg => try reloc.genArgDbgInfo(function), | 173 | .arg, |
| 174 | .dbg_arg_inline, | ||
| 175 | => try reloc.genArgDbgInfo(function), | ||
| 174 | 176 | ||
| 175 | .dbg_var_ptr, | 177 | .dbg_var_ptr, |
| 176 | .dbg_var_val, | 178 | .dbg_var_val, |
| ... | @@ -201,7 +203,7 @@ const DbgInfoReloc = struct { | ... | @@ -201,7 +203,7 @@ const DbgInfoReloc = struct { |
| 201 | else => unreachable, // not a possible argument | 203 | else => unreachable, // not a possible argument |
| 202 | 204 | ||
| 203 | }; | 205 | }; |
| 204 | try dw.genVarDebugInfo(.local_arg, reloc.name, reloc.ty, loc); | 206 | try dw.genLocalDebugInfo(.local_arg, reloc.name, reloc.ty, loc); |
| 205 | }, | 207 | }, |
| 206 | .plan9 => {}, | 208 | .plan9 => {}, |
| 207 | .none => {}, | 209 | .none => {}, |
| ... | @@ -237,7 +239,7 @@ const DbgInfoReloc = struct { | ... | @@ -237,7 +239,7 @@ const DbgInfoReloc = struct { |
| 237 | break :blk .empty; | 239 | break :blk .empty; |
| 238 | }, | 240 | }, |
| 239 | }; | 241 | }; |
| 240 | try dwarf.genVarDebugInfo(.local_var, reloc.name, reloc.ty, loc); | 242 | try dwarf.genLocalDebugInfo(.local_var, reloc.name, reloc.ty, loc); |
| 241 | }, | 243 | }, |
| 242 | .plan9 => {}, | 244 | .plan9 => {}, |
| 243 | .none => {}, | 245 | .none => {}, |
| ... | @@ -799,6 +801,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -799,6 +801,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 799 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | 801 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 800 | .dbg_var_ptr, | 802 | .dbg_var_ptr, |
| 801 | .dbg_var_val, | 803 | .dbg_var_val, |
| 804 | .dbg_arg_inline, | ||
| 802 | => try self.airDbgVar(inst), | 805 | => try self.airDbgVar(inst), |
| 803 | 806 | ||
| 804 | .call => try self.airCall(inst, .auto), | 807 | .call => try self.airCall(inst, .auto), |
| ... | @@ -4220,17 +4223,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4220,17 +4223,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4220 | 4223 | ||
| 4221 | const ty = self.typeOfIndex(inst); | 4224 | const ty = self.typeOfIndex(inst); |
| 4222 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 4225 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4223 | 4226 | const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | |
| 4224 | const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | 4227 | if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{ |
| 4225 | if (name_nts != .none) { | 4228 | .tag = tag, |
| 4226 | const name = self.air.nullTerminatedString(@intFromEnum(name_nts)); | 4229 | .ty = ty, |
| 4227 | try self.dbg_info_relocs.append(self.gpa, .{ | 4230 | .name = name.toSlice(self.air), |
| 4228 | .tag = tag, | 4231 | .mcv = self.args[arg_index], |
| 4229 | .ty = ty, | 4232 | }); |
| 4230 | .name = name, | ||
| 4231 | .mcv = self.args[arg_index], | ||
| 4232 | }); | ||
| 4233 | } | ||
| 4234 | 4233 | ||
| 4235 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; | 4234 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; |
| 4236 | return self.finishAir(inst, result, .{ .none, .none, .none }); | 4235 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| ... | @@ -4644,14 +4643,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4644,14 +4643,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 4644 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 4643 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4645 | const ty = self.typeOf(operand); | 4644 | const ty = self.typeOf(operand); |
| 4646 | const mcv = try self.resolveInst(operand); | 4645 | const mcv = try self.resolveInst(operand); |
| 4647 | const name = self.air.nullTerminatedString(pl_op.payload); | 4646 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 4648 | 4647 | ||
| 4649 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); | 4648 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); |
| 4650 | 4649 | ||
| 4651 | try self.dbg_info_relocs.append(self.gpa, .{ | 4650 | try self.dbg_info_relocs.append(self.gpa, .{ |
| 4652 | .tag = tag, | 4651 | .tag = tag, |
| 4653 | .ty = ty, | 4652 | .ty = ty, |
| 4654 | .name = name, | 4653 | .name = name.toSlice(self.air), |
| 4655 | .mcv = mcv, | 4654 | .mcv = mcv, |
| 4656 | }); | 4655 | }); |
| 4657 | 4656 |
src/arch/arm/CodeGen.zig+15-15| ... | @@ -248,7 +248,9 @@ const DbgInfoReloc = struct { | ... | @@ -248,7 +248,9 @@ const DbgInfoReloc = struct { |
| 248 | 248 | ||
| 249 | fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void { | 249 | fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void { |
| 250 | switch (reloc.tag) { | 250 | switch (reloc.tag) { |
| 251 | .arg => try reloc.genArgDbgInfo(function), | 251 | .arg, |
| 252 | .dbg_arg_inline, | ||
| 253 | => try reloc.genArgDbgInfo(function), | ||
| 252 | 254 | ||
| 253 | .dbg_var_ptr, | 255 | .dbg_var_ptr, |
| 254 | .dbg_var_val, | 256 | .dbg_var_val, |
| ... | @@ -279,7 +281,7 @@ const DbgInfoReloc = struct { | ... | @@ -279,7 +281,7 @@ const DbgInfoReloc = struct { |
| 279 | else => unreachable, // not a possible argument | 281 | else => unreachable, // not a possible argument |
| 280 | }; | 282 | }; |
| 281 | 283 | ||
| 282 | try dw.genVarDebugInfo(.local_arg, reloc.name, reloc.ty, loc); | 284 | try dw.genLocalDebugInfo(.local_arg, reloc.name, reloc.ty, loc); |
| 283 | }, | 285 | }, |
| 284 | .plan9 => {}, | 286 | .plan9 => {}, |
| 285 | .none => {}, | 287 | .none => {}, |
| ... | @@ -315,7 +317,7 @@ const DbgInfoReloc = struct { | ... | @@ -315,7 +317,7 @@ const DbgInfoReloc = struct { |
| 315 | break :blk .empty; | 317 | break :blk .empty; |
| 316 | }, | 318 | }, |
| 317 | }; | 319 | }; |
| 318 | try dw.genVarDebugInfo(.local_var, reloc.name, reloc.ty, loc); | 320 | try dw.genLocalDebugInfo(.local_var, reloc.name, reloc.ty, loc); |
| 319 | }, | 321 | }, |
| 320 | .plan9 => {}, | 322 | .plan9 => {}, |
| 321 | .none => {}, | 323 | .none => {}, |
| ... | @@ -786,6 +788,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -786,6 +788,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 786 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | 788 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 787 | .dbg_var_ptr, | 789 | .dbg_var_ptr, |
| 788 | .dbg_var_val, | 790 | .dbg_var_val, |
| 791 | .dbg_arg_inline, | ||
| 789 | => try self.airDbgVar(inst), | 792 | => try self.airDbgVar(inst), |
| 790 | 793 | ||
| 791 | .call => try self.airCall(inst, .auto), | 794 | .call => try self.airCall(inst, .auto), |
| ... | @@ -4199,16 +4202,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4199,16 +4202,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4199 | const ty = self.typeOfIndex(inst); | 4202 | const ty = self.typeOfIndex(inst); |
| 4200 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 4203 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4201 | 4204 | ||
| 4202 | const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | 4205 | const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; |
| 4203 | if (name_nts != .none) { | 4206 | if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{ |
| 4204 | const name = self.air.nullTerminatedString(@intFromEnum(name_nts)); | 4207 | .tag = tag, |
| 4205 | try self.dbg_info_relocs.append(self.gpa, .{ | 4208 | .ty = ty, |
| 4206 | .tag = tag, | 4209 | .name = name.toSlice(self.air), |
| 4207 | .ty = ty, | 4210 | .mcv = self.args[arg_index], |
| 4208 | .name = name, | 4211 | }); |
| 4209 | .mcv = self.args[arg_index], | ||
| 4210 | }); | ||
| 4211 | } | ||
| 4212 | 4212 | ||
| 4213 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; | 4213 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; |
| 4214 | return self.finishAir(inst, result, .{ .none, .none, .none }); | 4214 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| ... | @@ -4612,14 +4612,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4612,14 +4612,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 4612 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 4612 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4613 | const ty = self.typeOf(operand); | 4613 | const ty = self.typeOf(operand); |
| 4614 | const mcv = try self.resolveInst(operand); | 4614 | const mcv = try self.resolveInst(operand); |
| 4615 | const name = self.air.nullTerminatedString(pl_op.payload); | 4615 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 4616 | 4616 | ||
| 4617 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); | 4617 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); |
| 4618 | 4618 | ||
| 4619 | try self.dbg_info_relocs.append(self.gpa, .{ | 4619 | try self.dbg_info_relocs.append(self.gpa, .{ |
| 4620 | .tag = tag, | 4620 | .tag = tag, |
| 4621 | .ty = ty, | 4621 | .ty = ty, |
| 4622 | .name = name, | 4622 | .name = name.toSlice(self.air), |
| 4623 | .mcv = mcv, | 4623 | .mcv = mcv, |
| 4624 | }); | 4624 | }); |
| 4625 | 4625 |
src/arch/riscv64/CodeGen.zig+16-6| ... | @@ -1644,6 +1644,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1644,6 +1644,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1644 | 1644 | ||
| 1645 | .dbg_var_ptr, | 1645 | .dbg_var_ptr, |
| 1646 | .dbg_var_val, | 1646 | .dbg_var_val, |
| 1647 | .dbg_arg_inline, | ||
| 1647 | => try func.airDbgVar(inst), | 1648 | => try func.airDbgVar(inst), |
| 1648 | 1649 | ||
| 1649 | .dbg_inline_block => try func.airDbgInlineBlock(inst), | 1650 | .dbg_inline_block => try func.airDbgInlineBlock(inst), |
| ... | @@ -4673,11 +4674,15 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { | ... | @@ -4673,11 +4674,15 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { |
| 4673 | const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg; | 4674 | const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 4674 | const ty = arg.ty.toType(); | 4675 | const ty = arg.ty.toType(); |
| 4675 | if (arg.name == .none) return; | 4676 | if (arg.name == .none) return; |
| 4676 | const name = func.air.nullTerminatedString(@intFromEnum(arg.name)); | ||
| 4677 | 4677 | ||
| 4678 | switch (func.debug_output) { | 4678 | switch (func.debug_output) { |
| 4679 | .dwarf => |dw| switch (mcv) { | 4679 | .dwarf => |dw| switch (mcv) { |
| 4680 | .register => |reg| try dw.genVarDebugInfo(.local_arg, name, ty, .{ .reg = reg.dwarfNum() }), | 4680 | .register => |reg| try dw.genLocalDebugInfo( |
| 4681 | .local_arg, | ||
| 4682 | arg.name.toSlice(func.air), | ||
| 4683 | ty, | ||
| 4684 | .{ .reg = reg.dwarfNum() }, | ||
| 4685 | ), | ||
| 4681 | .load_frame => {}, | 4686 | .load_frame => {}, |
| 4682 | else => {}, | 4687 | else => {}, |
| 4683 | }, | 4688 | }, |
| ... | @@ -5179,16 +5184,17 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -5179,16 +5184,17 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void { |
| 5179 | const operand = pl_op.operand; | 5184 | const operand = pl_op.operand; |
| 5180 | const ty = func.typeOf(operand); | 5185 | const ty = func.typeOf(operand); |
| 5181 | const mcv = try func.resolveInst(operand); | 5186 | const mcv = try func.resolveInst(operand); |
| 5187 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); | ||
| 5182 | 5188 | ||
| 5183 | const name = func.air.nullTerminatedString(pl_op.payload); | 5189 | const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 5184 | 5190 | try func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air)); | |
| 5185 | try func.genVarDbgInfo(ty, mcv, name); | ||
| 5186 | 5191 | ||
| 5187 | return func.finishAir(inst, .unreach, .{ operand, .none, .none }); | 5192 | return func.finishAir(inst, .unreach, .{ operand, .none, .none }); |
| 5188 | } | 5193 | } |
| 5189 | 5194 | ||
| 5190 | fn genVarDbgInfo( | 5195 | fn genVarDbgInfo( |
| 5191 | func: Func, | 5196 | func: Func, |
| 5197 | tag: Air.Inst.Tag, | ||
| 5192 | ty: Type, | 5198 | ty: Type, |
| 5193 | mcv: MCValue, | 5199 | mcv: MCValue, |
| 5194 | name: []const u8, | 5200 | name: []const u8, |
| ... | @@ -5205,7 +5211,11 @@ fn genVarDbgInfo( | ... | @@ -5205,7 +5211,11 @@ fn genVarDbgInfo( |
| 5205 | break :blk .empty; | 5211 | break :blk .empty; |
| 5206 | }, | 5212 | }, |
| 5207 | }; | 5213 | }; |
| 5208 | try dwarf.genVarDebugInfo(.local_var, name, ty, loc); | 5214 | try dwarf.genLocalDebugInfo(switch (tag) { |
| 5215 | else => unreachable, | ||
| 5216 | .dbg_var_ptr, .dbg_var_val => .local_var, | ||
| 5217 | .dbg_arg_inline => .local_arg, | ||
| 5218 | }, name, ty, loc); | ||
| 5209 | }, | 5219 | }, |
| 5210 | .plan9 => {}, | 5220 | .plan9 => {}, |
| 5211 | .none => {}, | 5221 | .none => {}, |
src/arch/sparc64/CodeGen.zig+8-5| ... | @@ -643,6 +643,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -643,6 +643,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 643 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | 643 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 644 | .dbg_var_ptr, | 644 | .dbg_var_ptr, |
| 645 | .dbg_var_val, | 645 | .dbg_var_val, |
| 646 | .dbg_arg_inline, | ||
| 646 | => try self.airDbgVar(inst), | 647 | => try self.airDbgVar(inst), |
| 647 | 648 | ||
| 648 | .call => try self.airCall(inst, .auto), | 649 | .call => try self.airCall(inst, .auto), |
| ... | @@ -1662,7 +1663,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1662,7 +1663,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 1662 | 1663 | ||
| 1663 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 1664 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 1664 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 1665 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 1665 | const name = self.air.nullTerminatedString(pl_op.payload); | 1666 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 1666 | const operand = pl_op.operand; | 1667 | const operand = pl_op.operand; |
| 1667 | // TODO emit debug info for this variable | 1668 | // TODO emit debug info for this variable |
| 1668 | _ = name; | 1669 | _ = name; |
| ... | @@ -3582,13 +3583,15 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { | ... | @@ -3582,13 +3583,15 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { |
| 3582 | const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg; | 3583 | const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 3583 | const ty = arg.ty.toType(); | 3584 | const ty = arg.ty.toType(); |
| 3584 | if (arg.name == .none) return; | 3585 | if (arg.name == .none) return; |
| 3585 | const name = self.air.nullTerminatedString(@intFromEnum(arg.name)); | ||
| 3586 | 3586 | ||
| 3587 | switch (self.debug_output) { | 3587 | switch (self.debug_output) { |
| 3588 | .dwarf => |dw| switch (mcv) { | 3588 | .dwarf => |dw| switch (mcv) { |
| 3589 | .register => |reg| try dw.genVarDebugInfo(.local_arg, name, ty, .{ | 3589 | .register => |reg| try dw.genLocalDebugInfo( |
| 3590 | .reg = reg.dwarfNum(), | 3590 | .local_arg, |
| 3591 | }), | 3591 | arg.name.toSlice(self.air), |
| 3592 | ty, | ||
| 3593 | .{ .reg = reg.dwarfNum() }, | ||
| 3594 | ), | ||
| 3592 | else => {}, | 3595 | else => {}, |
| 3593 | }, | 3596 | }, |
| 3594 | else => {}, | 3597 | else => {}, |
src/arch/wasm/CodeGen.zig+19-13| ... | @@ -1917,8 +1917,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1917,8 +1917,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1917 | 1917 | ||
| 1918 | .dbg_stmt => func.airDbgStmt(inst), | 1918 | .dbg_stmt => func.airDbgStmt(inst), |
| 1919 | .dbg_inline_block => func.airDbgInlineBlock(inst), | 1919 | .dbg_inline_block => func.airDbgInlineBlock(inst), |
| 1920 | .dbg_var_ptr => func.airDbgVar(inst, true), | 1920 | .dbg_var_ptr => func.airDbgVar(inst, .local_var, true), |
| 1921 | .dbg_var_val => func.airDbgVar(inst, false), | 1921 | .dbg_var_val => func.airDbgVar(inst, .local_var, false), |
| 1922 | .dbg_arg_inline => func.airDbgVar(inst, .local_arg, false), | ||
| 1922 | 1923 | ||
| 1923 | .call => func.airCall(inst, .auto), | 1924 | .call => func.airCall(inst, .auto), |
| 1924 | .call_always_tail => func.airCall(inst, .always_tail), | 1925 | .call_always_tail => func.airCall(inst, .always_tail), |
| ... | @@ -2585,13 +2586,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2585,13 +2586,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2585 | 2586 | ||
| 2586 | switch (func.debug_output) { | 2587 | switch (func.debug_output) { |
| 2587 | .dwarf => |dwarf| { | 2588 | .dwarf => |dwarf| { |
| 2588 | const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | 2589 | const name = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; |
| 2589 | if (name_nts != .none) { | 2590 | if (name != .none) try dwarf.genLocalDebugInfo( |
| 2590 | const name = func.air.nullTerminatedString(@intFromEnum(name_nts)); | 2591 | .local_arg, |
| 2591 | try dwarf.genVarDebugInfo(.local_arg, name, arg_ty, .{ | 2592 | name.toSlice(func.air), |
| 2592 | .wasm_ext = .{ .local = arg.local.value }, | 2593 | arg_ty, |
| 2593 | }); | 2594 | .{ .wasm_ext = .{ .local = arg.local.value } }, |
| 2594 | } | 2595 | ); |
| 2595 | }, | 2596 | }, |
| 2596 | else => {}, | 2597 | else => {}, |
| 2597 | } | 2598 | } |
| ... | @@ -6454,7 +6455,12 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6454,7 +6455,12 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6454 | try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len])); | 6455 | try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len])); |
| 6455 | } | 6456 | } |
| 6456 | 6457 | ||
| 6457 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void { | 6458 | fn airDbgVar( |
| 6459 | func: *CodeGen, | ||
| 6460 | inst: Air.Inst.Index, | ||
| 6461 | local_tag: link.File.Dwarf.WipNav.LocalTag, | ||
| 6462 | is_ptr: bool, | ||
| 6463 | ) InnerError!void { | ||
| 6458 | _ = is_ptr; | 6464 | _ = is_ptr; |
| 6459 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); | 6465 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); |
| 6460 | 6466 | ||
| ... | @@ -6464,8 +6470,8 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void | ... | @@ -6464,8 +6470,8 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void |
| 6464 | 6470 | ||
| 6465 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand }); | 6471 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand }); |
| 6466 | 6472 | ||
| 6467 | const name = func.air.nullTerminatedString(pl_op.payload); | 6473 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 6468 | log.debug(" var name = ({s})", .{name}); | 6474 | log.debug(" var name = ({s})", .{name.toSlice(func.air)}); |
| 6469 | 6475 | ||
| 6470 | const loc: link.File.Dwarf.Loc = switch (operand) { | 6476 | const loc: link.File.Dwarf.Loc = switch (operand) { |
| 6471 | .local => |local| .{ .wasm_ext = .{ .local = local.value } }, | 6477 | .local => |local| .{ .wasm_ext = .{ .local = local.value } }, |
| ... | @@ -6474,7 +6480,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void | ... | @@ -6474,7 +6480,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void |
| 6474 | break :blk .empty; | 6480 | break :blk .empty; |
| 6475 | }, | 6481 | }, |
| 6476 | }; | 6482 | }; |
| 6477 | try func.debug_output.dwarf.genVarDebugInfo(.local_var, name, ty, loc); | 6483 | try func.debug_output.dwarf.genLocalDebugInfo(local_tag, name.toSlice(func.air), ty, loc); |
| 6478 | 6484 | ||
| 6479 | return func.finishAir(inst, .none, &.{}); | 6485 | return func.finishAir(inst, .none, &.{}); |
| 6480 | } | 6486 | } |
src/arch/x86_64/CodeGen.zig+268-238| ... | @@ -64,8 +64,8 @@ va_info: union { | ... | @@ -64,8 +64,8 @@ va_info: union { |
| 64 | sysv: struct { | 64 | sysv: struct { |
| 65 | gp_count: u32, | 65 | gp_count: u32, |
| 66 | fp_count: u32, | 66 | fp_count: u32, |
| 67 | overflow_arg_area: FrameAddr, | 67 | overflow_arg_area: bits.FrameAddr, |
| 68 | reg_save_area: FrameAddr, | 68 | reg_save_area: bits.FrameAddr, |
| 69 | }, | 69 | }, |
| 70 | win64: struct {}, | 70 | win64: struct {}, |
| 71 | }, | 71 | }, |
| ... | @@ -81,9 +81,6 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, | ... | @@ -81,9 +81,6 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, |
| 81 | /// MIR extra data | 81 | /// MIR extra data |
| 82 | mir_extra: std.ArrayListUnmanaged(u32) = .{}, | 82 | mir_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 83 | 83 | ||
| 84 | stack_args: std.ArrayListUnmanaged(StackVar) = .{}, | ||
| 85 | stack_vars: std.ArrayListUnmanaged(StackVar) = .{}, | ||
| 86 | |||
| 87 | /// Byte offset within the source file of the ending curly. | 84 | /// Byte offset within the source file of the ending curly. |
| 88 | end_di_line: u32, | 85 | end_di_line: u32, |
| 89 | end_di_column: u32, | 86 | end_di_column: u32, |
| ... | @@ -113,10 +110,6 @@ air_bookkeeping: @TypeOf(air_bookkeeping_init) = air_bookkeeping_init, | ... | @@ -113,10 +110,6 @@ air_bookkeeping: @TypeOf(air_bookkeeping_init) = air_bookkeeping_init, |
| 113 | 110 | ||
| 114 | const air_bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {}; | 111 | const air_bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {}; |
| 115 | 112 | ||
| 116 | const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; | ||
| 117 | const RegisterOffset = struct { reg: Register, off: i32 = 0 }; | ||
| 118 | const SymbolOffset = struct { sym: u32, off: i32 = 0 }; | ||
| 119 | |||
| 120 | const Owner = union(enum) { | 113 | const Owner = union(enum) { |
| 121 | nav_index: InternPool.Nav.Index, | 114 | nav_index: InternPool.Nav.Index, |
| 122 | lazy_sym: link.File.LazySymbol, | 115 | lazy_sym: link.File.LazySymbol, |
| ... | @@ -174,7 +167,7 @@ pub const MCValue = union(enum) { | ... | @@ -174,7 +167,7 @@ pub const MCValue = union(enum) { |
| 174 | /// The value is split across two registers. | 167 | /// The value is split across two registers. |
| 175 | register_pair: [2]Register, | 168 | register_pair: [2]Register, |
| 176 | /// The value is a constant offset from the value in a register. | 169 | /// The value is a constant offset from the value in a register. |
| 177 | register_offset: RegisterOffset, | 170 | register_offset: bits.RegisterOffset, |
| 178 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the GP register. | 171 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the GP register. |
| 179 | register_overflow: struct { reg: Register, eflags: Condition }, | 172 | register_overflow: struct { reg: Register, eflags: Condition }, |
| 180 | /// The value is in memory at a hard-coded address. | 173 | /// The value is in memory at a hard-coded address. |
| ... | @@ -182,11 +175,11 @@ pub const MCValue = union(enum) { | ... | @@ -182,11 +175,11 @@ pub const MCValue = union(enum) { |
| 182 | memory: u64, | 175 | memory: u64, |
| 183 | /// The value is in memory at an address not-yet-allocated by the linker. | 176 | /// The value is in memory at an address not-yet-allocated by the linker. |
| 184 | /// This traditionally corresponds to a relocation emitted in a relocatable object file. | 177 | /// This traditionally corresponds to a relocation emitted in a relocatable object file. |
| 185 | load_symbol: SymbolOffset, | 178 | load_symbol: bits.SymbolOffset, |
| 186 | /// The address of the memory location not-yet-allocated by the linker. | 179 | /// The address of the memory location not-yet-allocated by the linker. |
| 187 | lea_symbol: SymbolOffset, | 180 | lea_symbol: bits.SymbolOffset, |
| 188 | /// The value is in memory at a constant offset from the address in a register. | 181 | /// The value is in memory at a constant offset from the address in a register. |
| 189 | indirect: RegisterOffset, | 182 | indirect: bits.RegisterOffset, |
| 190 | /// The value is in memory. | 183 | /// The value is in memory. |
| 191 | /// Payload is a symbol index. | 184 | /// Payload is a symbol index. |
| 192 | load_direct: u32, | 185 | load_direct: u32, |
| ... | @@ -207,10 +200,10 @@ pub const MCValue = union(enum) { | ... | @@ -207,10 +200,10 @@ pub const MCValue = union(enum) { |
| 207 | lea_tlv: u32, | 200 | lea_tlv: u32, |
| 208 | /// The value stored at an offset from a frame index | 201 | /// The value stored at an offset from a frame index |
| 209 | /// Payload is a frame address. | 202 | /// Payload is a frame address. |
| 210 | load_frame: FrameAddr, | 203 | load_frame: bits.FrameAddr, |
| 211 | /// The address of an offset from a frame index | 204 | /// The address of an offset from a frame index |
| 212 | /// Payload is a frame address. | 205 | /// Payload is a frame address. |
| 213 | lea_frame: FrameAddr, | 206 | lea_frame: bits.FrameAddr, |
| 214 | /// Supports integer_per_element abi | 207 | /// Supports integer_per_element abi |
| 215 | elementwise_regs_then_frame: packed struct { regs: u3 = 0, frame_off: i29 = 0, frame_index: FrameIndex }, | 208 | elementwise_regs_then_frame: packed struct { regs: u3 = 0, frame_off: i29 = 0, frame_index: FrameIndex }, |
| 216 | /// This indicates that we have already allocated a frame index for this instruction, | 209 | /// This indicates that we have already allocated a frame index for this instruction, |
| ... | @@ -426,10 +419,7 @@ pub const MCValue = union(enum) { | ... | @@ -426,10 +419,7 @@ pub const MCValue = union(enum) { |
| 426 | .load_symbol => |sym_off| { | 419 | .load_symbol => |sym_off| { |
| 427 | assert(sym_off.off == 0); | 420 | assert(sym_off.off == 0); |
| 428 | return .{ | 421 | return .{ |
| 429 | .base = .{ .reloc = .{ | 422 | .base = .{ .reloc = sym_off.sym_index }, |
| 430 | .atom_index = try function.owner.getSymbolIndex(function), | ||
| 431 | .sym_index = sym_off.sym, | ||
| 432 | } }, | ||
| 433 | .mod = .{ .rm = .{ | 423 | .mod = .{ .rm = .{ |
| 434 | .size = size, | 424 | .size = size, |
| 435 | .disp = sym_off.off, | 425 | .disp = sym_off.off, |
| ... | @@ -456,8 +446,8 @@ pub const MCValue = union(enum) { | ... | @@ -456,8 +446,8 @@ pub const MCValue = union(enum) { |
| 456 | .register_overflow => |pl| try writer.print("{s}:{s}", .{ | 446 | .register_overflow => |pl| try writer.print("{s}:{s}", .{ |
| 457 | @tagName(pl.eflags), @tagName(pl.reg), | 447 | @tagName(pl.eflags), @tagName(pl.reg), |
| 458 | }), | 448 | }), |
| 459 | .load_symbol => |pl| try writer.print("[{} + 0x{x}]", .{ pl.sym, pl.off }), | 449 | .load_symbol => |pl| try writer.print("[{} + 0x{x}]", .{ pl.sym_index, pl.off }), |
| 460 | .lea_symbol => |pl| try writer.print("{} + 0x{x}", .{ pl.sym, pl.off }), | 450 | .lea_symbol => |pl| try writer.print("{} + 0x{x}", .{ pl.sym_index, pl.off }), |
| 461 | .indirect => |pl| try writer.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }), | 451 | .indirect => |pl| try writer.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }), |
| 462 | .load_direct => |pl| try writer.print("[direct:{d}]", .{pl}), | 452 | .load_direct => |pl| try writer.print("[direct:{d}]", .{pl}), |
| 463 | .lea_direct => |pl| try writer.print("direct:{d}", .{pl}), | 453 | .lea_direct => |pl| try writer.print("direct:{d}", .{pl}), |
| ... | @@ -728,12 +718,6 @@ const InstTracking = struct { | ... | @@ -728,12 +718,6 @@ const InstTracking = struct { |
| 728 | } | 718 | } |
| 729 | }; | 719 | }; |
| 730 | 720 | ||
| 731 | const StackVar = struct { | ||
| 732 | name: []const u8, | ||
| 733 | type: Type, | ||
| 734 | frame_addr: FrameAddr, | ||
| 735 | }; | ||
| 736 | |||
| 737 | const FrameAlloc = struct { | 721 | const FrameAlloc = struct { |
| 738 | abi_size: u31, | 722 | abi_size: u31, |
| 739 | spill_pad: u3, | 723 | spill_pad: u3, |
| ... | @@ -839,8 +823,6 @@ pub fn generate( | ... | @@ -839,8 +823,6 @@ pub fn generate( |
| 839 | function.exitlude_jump_relocs.deinit(gpa); | 823 | function.exitlude_jump_relocs.deinit(gpa); |
| 840 | function.mir_instructions.deinit(gpa); | 824 | function.mir_instructions.deinit(gpa); |
| 841 | function.mir_extra.deinit(gpa); | 825 | function.mir_extra.deinit(gpa); |
| 842 | function.stack_args.deinit(gpa); | ||
| 843 | function.stack_vars.deinit(gpa); | ||
| 844 | } | 826 | } |
| 845 | 827 | ||
| 846 | wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)}); | 828 | wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)}); |
| ... | @@ -913,9 +895,6 @@ pub fn generate( | ... | @@ -913,9 +895,6 @@ pub fn generate( |
| 913 | else => |e| return e, | 895 | else => |e| return e, |
| 914 | }; | 896 | }; |
| 915 | 897 | ||
| 916 | try function.genStackVarDebugInfo(.local_arg, function.stack_args.items); | ||
| 917 | try function.genStackVarDebugInfo(.local_var, function.stack_vars.items); | ||
| 918 | |||
| 919 | var mir: Mir = .{ | 898 | var mir: Mir = .{ |
| 920 | .instructions = function.mir_instructions.toOwnedSlice(), | 899 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 921 | .extra = try function.mir_extra.toOwnedSlice(gpa), | 900 | .extra = try function.mir_extra.toOwnedSlice(gpa), |
| ... | @@ -924,6 +903,7 @@ pub fn generate( | ... | @@ -924,6 +903,7 @@ pub fn generate( |
| 924 | defer mir.deinit(gpa); | 903 | defer mir.deinit(gpa); |
| 925 | 904 | ||
| 926 | var emit: Emit = .{ | 905 | var emit: Emit = .{ |
| 906 | .air = function.air, | ||
| 927 | .lower = .{ | 907 | .lower = .{ |
| 928 | .bin_file = bin_file, | 908 | .bin_file = bin_file, |
| 929 | .allocator = gpa, | 909 | .allocator = gpa, |
| ... | @@ -934,6 +914,13 @@ pub fn generate( | ... | @@ -934,6 +914,13 @@ pub fn generate( |
| 934 | .link_mode = comp.config.link_mode, | 914 | .link_mode = comp.config.link_mode, |
| 935 | .pic = mod.pic, | 915 | .pic = mod.pic, |
| 936 | }, | 916 | }, |
| 917 | .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) { | ||
| 918 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, | ||
| 919 | error.OutOfRegisters => return Result{ | ||
| 920 | .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), | ||
| 921 | }, | ||
| 922 | else => |e| return e, | ||
| 923 | }, | ||
| 937 | .debug_output = debug_output, | 924 | .debug_output = debug_output, |
| 938 | .code = code, | 925 | .code = code, |
| 939 | .prev_di_pc = 0, | 926 | .prev_di_pc = 0, |
| ... | @@ -1013,14 +1000,15 @@ pub fn generateLazy( | ... | @@ -1013,14 +1000,15 @@ pub fn generateLazy( |
| 1013 | else => |e| return e, | 1000 | else => |e| return e, |
| 1014 | }; | 1001 | }; |
| 1015 | 1002 | ||
| 1016 | var mir = Mir{ | 1003 | var mir: Mir = .{ |
| 1017 | .instructions = function.mir_instructions.toOwnedSlice(), | 1004 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 1018 | .extra = try function.mir_extra.toOwnedSlice(gpa), | 1005 | .extra = try function.mir_extra.toOwnedSlice(gpa), |
| 1019 | .frame_locs = function.frame_locs.toOwnedSlice(), | 1006 | .frame_locs = function.frame_locs.toOwnedSlice(), |
| 1020 | }; | 1007 | }; |
| 1021 | defer mir.deinit(gpa); | 1008 | defer mir.deinit(gpa); |
| 1022 | 1009 | ||
| 1023 | var emit = Emit{ | 1010 | var emit: Emit = .{ |
| 1011 | .air = function.air, | ||
| 1024 | .lower = .{ | 1012 | .lower = .{ |
| 1025 | .bin_file = bin_file, | 1013 | .bin_file = bin_file, |
| 1026 | .allocator = gpa, | 1014 | .allocator = gpa, |
| ... | @@ -1031,6 +1019,13 @@ pub fn generateLazy( | ... | @@ -1031,6 +1019,13 @@ pub fn generateLazy( |
| 1031 | .link_mode = comp.config.link_mode, | 1019 | .link_mode = comp.config.link_mode, |
| 1032 | .pic = mod.pic, | 1020 | .pic = mod.pic, |
| 1033 | }, | 1021 | }, |
| 1022 | .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) { | ||
| 1023 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, | ||
| 1024 | error.OutOfRegisters => return Result{ | ||
| 1025 | .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), | ||
| 1026 | }, | ||
| 1027 | else => |e| return e, | ||
| 1028 | }, | ||
| 1034 | .debug_output = debug_output, | 1029 | .debug_output = debug_output, |
| 1035 | .code = code, | 1030 | .code = code, |
| 1036 | .prev_di_pc = undefined, // no debug info yet | 1031 | .prev_di_pc = undefined, // no debug info yet |
| ... | @@ -1116,7 +1111,7 @@ fn formatWipMir( | ... | @@ -1116,7 +1111,7 @@ fn formatWipMir( |
| 1116 | ) @TypeOf(writer).Error!void { | 1111 | ) @TypeOf(writer).Error!void { |
| 1117 | const comp = data.self.bin_file.comp; | 1112 | const comp = data.self.bin_file.comp; |
| 1118 | const mod = comp.root_mod; | 1113 | const mod = comp.root_mod; |
| 1119 | var lower = Lower{ | 1114 | var lower: Lower = .{ |
| 1120 | .bin_file = data.self.bin_file, | 1115 | .bin_file = data.self.bin_file, |
| 1121 | .allocator = data.self.gpa, | 1116 | .allocator = data.self.gpa, |
| 1122 | .mir = .{ | 1117 | .mir = .{ |
| ... | @@ -1204,6 +1199,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | ... | @@ -1204,6 +1199,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 1204 | self.mir_extra.appendAssumeCapacity(switch (field.type) { | 1199 | self.mir_extra.appendAssumeCapacity(switch (field.type) { |
| 1205 | u32 => @field(extra, field.name), | 1200 | u32 => @field(extra, field.name), |
| 1206 | i32, Mir.Memory.Info => @bitCast(@field(extra, field.name)), | 1201 | i32, Mir.Memory.Info => @bitCast(@field(extra, field.name)), |
| 1202 | bits.FrameIndex => @intFromEnum(@field(extra, field.name)), | ||
| 1207 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), | 1203 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), |
| 1208 | }); | 1204 | }); |
| 1209 | } | 1205 | } |
| ... | @@ -1357,6 +1353,124 @@ fn asmPlaceholder(self: *Self) !Mir.Inst.Index { | ... | @@ -1357,6 +1353,124 @@ fn asmPlaceholder(self: *Self) !Mir.Inst.Index { |
| 1357 | }); | 1353 | }); |
| 1358 | } | 1354 | } |
| 1359 | 1355 | ||
| 1356 | const MirTagAir = enum { dbg_local }; | ||
| 1357 | |||
| 1358 | fn asmAir(self: *Self, tag: MirTagAir, inst: Air.Inst.Index) !void { | ||
| 1359 | _ = try self.addInst(.{ | ||
| 1360 | .tag = .pseudo, | ||
| 1361 | .ops = switch (tag) { | ||
| 1362 | .dbg_local => .pseudo_dbg_local_a, | ||
| 1363 | }, | ||
| 1364 | .data = .{ .a = .{ .air_inst = inst } }, | ||
| 1365 | }); | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | fn asmAirImmediate(self: *Self, tag: MirTagAir, inst: Air.Inst.Index, imm: Immediate) !void { | ||
| 1369 | switch (imm) { | ||
| 1370 | .signed => |s| _ = try self.addInst(.{ | ||
| 1371 | .tag = .pseudo, | ||
| 1372 | .ops = switch (tag) { | ||
| 1373 | .dbg_local => .pseudo_dbg_local_ai_s, | ||
| 1374 | }, | ||
| 1375 | .data = .{ .ai = .{ | ||
| 1376 | .air_inst = inst, | ||
| 1377 | .i = @bitCast(s), | ||
| 1378 | } }, | ||
| 1379 | }), | ||
| 1380 | .unsigned => |u| _ = if (math.cast(u32, u)) |small| try self.addInst(.{ | ||
| 1381 | .tag = .pseudo, | ||
| 1382 | .ops = switch (tag) { | ||
| 1383 | .dbg_local => .pseudo_dbg_local_ai_u, | ||
| 1384 | }, | ||
| 1385 | .data = .{ .ai = .{ | ||
| 1386 | .air_inst = inst, | ||
| 1387 | .i = small, | ||
| 1388 | } }, | ||
| 1389 | }) else try self.addInst(.{ | ||
| 1390 | .tag = .pseudo, | ||
| 1391 | .ops = switch (tag) { | ||
| 1392 | .dbg_local => .pseudo_dbg_local_ai_64, | ||
| 1393 | }, | ||
| 1394 | .data = .{ .ai = .{ | ||
| 1395 | .air_inst = inst, | ||
| 1396 | .i = try self.addExtra(Mir.Imm64.encode(u)), | ||
| 1397 | } }, | ||
| 1398 | }), | ||
| 1399 | .reloc => |sym_off| _ = if (sym_off.off == 0) try self.addInst(.{ | ||
| 1400 | .tag = .pseudo, | ||
| 1401 | .ops = switch (tag) { | ||
| 1402 | .dbg_local => .pseudo_dbg_local_as, | ||
| 1403 | }, | ||
| 1404 | .data = .{ .as = .{ | ||
| 1405 | .air_inst = inst, | ||
| 1406 | .sym_index = sym_off.sym_index, | ||
| 1407 | } }, | ||
| 1408 | }) else try self.addInst(.{ | ||
| 1409 | .tag = .pseudo, | ||
| 1410 | .ops = switch (tag) { | ||
| 1411 | .dbg_local => .pseudo_dbg_local_aso, | ||
| 1412 | }, | ||
| 1413 | .data = .{ .ax = .{ | ||
| 1414 | .air_inst = inst, | ||
| 1415 | .payload = try self.addExtra(sym_off), | ||
| 1416 | } }, | ||
| 1417 | }), | ||
| 1418 | } | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | fn asmAirRegisterImmediate( | ||
| 1422 | self: *Self, | ||
| 1423 | tag: MirTagAir, | ||
| 1424 | inst: Air.Inst.Index, | ||
| 1425 | reg: Register, | ||
| 1426 | imm: Immediate, | ||
| 1427 | ) !void { | ||
| 1428 | _ = try self.addInst(.{ | ||
| 1429 | .tag = .pseudo, | ||
| 1430 | .ops = switch (tag) { | ||
| 1431 | .dbg_local => .pseudo_dbg_local_aro, | ||
| 1432 | }, | ||
| 1433 | .data = .{ .rx = .{ | ||
| 1434 | .r1 = reg, | ||
| 1435 | .payload = try self.addExtra(Mir.AirOffset{ | ||
| 1436 | .air_inst = inst, | ||
| 1437 | .off = imm.signed, | ||
| 1438 | }), | ||
| 1439 | } }, | ||
| 1440 | }); | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | fn asmAirFrameAddress( | ||
| 1444 | self: *Self, | ||
| 1445 | tag: MirTagAir, | ||
| 1446 | inst: Air.Inst.Index, | ||
| 1447 | frame_addr: bits.FrameAddr, | ||
| 1448 | ) !void { | ||
| 1449 | _ = try self.addInst(.{ | ||
| 1450 | .tag = .pseudo, | ||
| 1451 | .ops = switch (tag) { | ||
| 1452 | .dbg_local => .pseudo_dbg_local_af, | ||
| 1453 | }, | ||
| 1454 | .data = .{ .ax = .{ | ||
| 1455 | .air_inst = inst, | ||
| 1456 | .payload = try self.addExtra(frame_addr), | ||
| 1457 | } }, | ||
| 1458 | }); | ||
| 1459 | } | ||
| 1460 | |||
| 1461 | fn asmAirMemory(self: *Self, tag: MirTagAir, inst: Air.Inst.Index, m: Memory) !void { | ||
| 1462 | _ = try self.addInst(.{ | ||
| 1463 | .tag = .pseudo, | ||
| 1464 | .ops = switch (tag) { | ||
| 1465 | .dbg_local => .pseudo_dbg_local_am, | ||
| 1466 | }, | ||
| 1467 | .data = .{ .ax = .{ | ||
| 1468 | .air_inst = inst, | ||
| 1469 | .payload = try self.addExtra(Mir.Memory.encode(m)), | ||
| 1470 | } }, | ||
| 1471 | }); | ||
| 1472 | } | ||
| 1473 | |||
| 1360 | fn asmOpOnly(self: *Self, tag: Mir.Inst.FixedTag) !void { | 1474 | fn asmOpOnly(self: *Self, tag: Mir.Inst.FixedTag) !void { |
| 1361 | _ = try self.addInst(.{ | 1475 | _ = try self.addInst(.{ |
| 1362 | .tag = tag[1], | 1476 | .tag = tag[1], |
| ... | @@ -1395,9 +1509,9 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void { | ... | @@ -1395,9 +1509,9 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void { |
| 1395 | .reloc => .rel, | 1509 | .reloc => .rel, |
| 1396 | }, | 1510 | }, |
| 1397 | .data = switch (imm) { | 1511 | .data = switch (imm) { |
| 1398 | .reloc => |x| reloc: { | 1512 | .reloc => |sym_off| reloc: { |
| 1399 | assert(tag[0] == ._); | 1513 | assert(tag[0] == ._); |
| 1400 | break :reloc .{ .reloc = x }; | 1514 | break :reloc .{ .reloc = sym_off }; |
| 1401 | }, | 1515 | }, |
| 1402 | .signed, .unsigned => .{ .i = .{ | 1516 | .signed, .unsigned => .{ .i = .{ |
| 1403 | .fixes = tag[0], | 1517 | .fixes = tag[0], |
| ... | @@ -1424,31 +1538,22 @@ fn asmRegisterRegister(self: *Self, tag: Mir.Inst.FixedTag, reg1: Register, reg2 | ... | @@ -1424,31 +1538,22 @@ fn asmRegisterRegister(self: *Self, tag: Mir.Inst.FixedTag, reg1: Register, reg2 |
| 1424 | } | 1538 | } |
| 1425 | 1539 | ||
| 1426 | fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: Immediate) !void { | 1540 | fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: Immediate) !void { |
| 1427 | const ops: Mir.Inst.Ops = switch (imm) { | 1541 | const ops: Mir.Inst.Ops, const i: u32 = switch (imm) { |
| 1428 | .signed => .ri_s, | 1542 | .signed => |s| .{ .ri_s, @bitCast(s) }, |
| 1429 | .unsigned => |u| if (math.cast(u32, u)) |_| .ri_u else .ri64, | 1543 | .unsigned => |u| if (math.cast(u32, u)) |small| |
| 1544 | .{ .ri_u, small } | ||
| 1545 | else | ||
| 1546 | .{ .ri_64, try self.addExtra(Mir.Imm64.encode(imm.unsigned)) }, | ||
| 1430 | .reloc => unreachable, | 1547 | .reloc => unreachable, |
| 1431 | }; | 1548 | }; |
| 1432 | _ = try self.addInst(.{ | 1549 | _ = try self.addInst(.{ |
| 1433 | .tag = tag[1], | 1550 | .tag = tag[1], |
| 1434 | .ops = ops, | 1551 | .ops = ops, |
| 1435 | .data = switch (ops) { | 1552 | .data = .{ .ri = .{ |
| 1436 | .ri_s, .ri_u => .{ .ri = .{ | 1553 | .fixes = tag[0], |
| 1437 | .fixes = tag[0], | 1554 | .r1 = reg, |
| 1438 | .r1 = reg, | 1555 | .i = i, |
| 1439 | .i = switch (imm) { | 1556 | } }, |
| 1440 | .signed => |s| @bitCast(s), | ||
| 1441 | .unsigned => |u| @intCast(u), | ||
| 1442 | .reloc => unreachable, | ||
| 1443 | }, | ||
| 1444 | } }, | ||
| 1445 | .ri64 => .{ .rx = .{ | ||
| 1446 | .fixes = tag[0], | ||
| 1447 | .r1 = reg, | ||
| 1448 | .payload = try self.addExtra(Mir.Imm64.encode(imm.unsigned)), | ||
| 1449 | } }, | ||
| 1450 | else => unreachable, | ||
| 1451 | }, | ||
| 1452 | }); | 1557 | }); |
| 1453 | } | 1558 | } |
| 1454 | 1559 | ||
| ... | @@ -2158,6 +2263,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2158,6 +2263,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2158 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | 2263 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 2159 | .dbg_var_ptr, | 2264 | .dbg_var_ptr, |
| 2160 | .dbg_var_val, | 2265 | .dbg_var_val, |
| 2266 | .dbg_arg_inline, | ||
| 2161 | => try self.airDbgVar(inst), | 2267 | => try self.airDbgVar(inst), |
| 2162 | 2268 | ||
| 2163 | .call => try self.airCall(inst, .auto), | 2269 | .call => try self.airCall(inst, .auto), |
| ... | @@ -2485,12 +2591,12 @@ fn computeFrameLayout(self: *Self, cc: std.builtin.CallingConvention) !FrameLayo | ... | @@ -2485,12 +2591,12 @@ fn computeFrameLayout(self: *Self, cc: std.builtin.CallingConvention) !FrameLayo |
| 2485 | }; | 2591 | }; |
| 2486 | } | 2592 | } |
| 2487 | 2593 | ||
| 2488 | fn getFrameAddrAlignment(self: *Self, frame_addr: FrameAddr) Alignment { | 2594 | fn getFrameAddrAlignment(self: *Self, frame_addr: bits.FrameAddr) Alignment { |
| 2489 | const alloc_align = self.frame_allocs.get(@intFromEnum(frame_addr.index)).abi_align; | 2595 | const alloc_align = self.frame_allocs.get(@intFromEnum(frame_addr.index)).abi_align; |
| 2490 | return @enumFromInt(@min(@intFromEnum(alloc_align), @ctz(frame_addr.off))); | 2596 | return @enumFromInt(@min(@intFromEnum(alloc_align), @ctz(frame_addr.off))); |
| 2491 | } | 2597 | } |
| 2492 | 2598 | ||
| 2493 | fn getFrameAddrSize(self: *Self, frame_addr: FrameAddr) u32 { | 2599 | fn getFrameAddrSize(self: *Self, frame_addr: bits.FrameAddr) u32 { |
| 2494 | return self.frame_allocs.get(@intFromEnum(frame_addr.index)).abi_size - @as(u31, @intCast(frame_addr.off)); | 2600 | return self.frame_allocs.get(@intFromEnum(frame_addr.index)).abi_size - @as(u31, @intCast(frame_addr.off)); |
| 2495 | } | 2601 | } |
| 2496 | 2602 | ||
| ... | @@ -11951,87 +12057,65 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11951,87 +12057,65 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 11951 | fn airDbgArg(self: *Self, inst: Air.Inst.Index) !void { | 12057 | fn airDbgArg(self: *Self, inst: Air.Inst.Index) !void { |
| 11952 | defer self.finishAirBookkeeping(); | 12058 | defer self.finishAirBookkeeping(); |
| 11953 | if (self.debug_output == .none) return; | 12059 | if (self.debug_output == .none) return; |
| 11954 | const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | 12060 | const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; |
| 11955 | const name = self.air.nullTerminatedString(@intFromEnum(name_nts)); | 12061 | if (name != .none) try self.genLocalDebugInfo(inst, self.getResolvedInstValue(inst).short); |
| 11956 | if (name.len > 0) { | ||
| 11957 | const arg_ty = self.typeOfIndex(inst); | ||
| 11958 | const arg_mcv = self.getResolvedInstValue(inst).short; | ||
| 11959 | try self.genVarDebugInfo(.local_arg, .dbg_var_val, name, arg_ty, arg_mcv); | ||
| 11960 | } | ||
| 11961 | if (self.liveness.isUnused(inst)) try self.processDeath(inst); | 12062 | if (self.liveness.isUnused(inst)) try self.processDeath(inst); |
| 11962 | } | 12063 | } |
| 11963 | 12064 | ||
| 11964 | fn genVarDebugInfo( | 12065 | fn genLocalDebugInfo( |
| 11965 | self: *Self, | 12066 | self: *Self, |
| 11966 | var_tag: link.File.Dwarf.WipNav.VarTag, | 12067 | inst: Air.Inst.Index, |
| 11967 | tag: Air.Inst.Tag, | ||
| 11968 | name: []const u8, | ||
| 11969 | ty: Type, | ||
| 11970 | mcv: MCValue, | 12068 | mcv: MCValue, |
| 11971 | ) !void { | 12069 | ) !void { |
| 11972 | const stack_vars = switch (var_tag) { | 12070 | if (self.debug_output == .none) return; |
| 11973 | .local_arg => &self.stack_args, | 12071 | switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) { |
| 11974 | .local_var => &self.stack_vars, | 12072 | else => unreachable, |
| 11975 | }; | 12073 | .arg, .dbg_arg_inline, .dbg_var_val => |tag| { |
| 11976 | switch (self.debug_output) { | 12074 | switch (mcv) { |
| 11977 | .dwarf => |dwarf| switch (tag) { | 12075 | .none => try self.asmAir(.dbg_local, inst), |
| 11978 | else => unreachable, | ||
| 11979 | .dbg_var_ptr => { | ||
| 11980 | const var_ty = ty.childType(self.pt.zcu); | ||
| 11981 | switch (mcv) { | ||
| 11982 | else => { | ||
| 11983 | log.info("dbg_var_ptr({s}({}))", .{ @tagName(mcv), mcv }); | ||
| 11984 | unreachable; | ||
| 11985 | }, | ||
| 11986 | .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable, | ||
| 11987 | .lea_frame => |frame_addr| try stack_vars.append(self.gpa, .{ | ||
| 11988 | .name = name, | ||
| 11989 | .type = var_ty, | ||
| 11990 | .frame_addr = frame_addr, | ||
| 11991 | }), | ||
| 11992 | .lea_symbol => |sym_off| try dwarf.genVarDebugInfo(var_tag, name, var_ty, .{ .plus = .{ | ||
| 11993 | &.{ .addr = .{ .sym = sym_off.sym } }, | ||
| 11994 | &.{ .consts = sym_off.off }, | ||
| 11995 | } }), | ||
| 11996 | } | ||
| 11997 | }, | ||
| 11998 | .dbg_var_val => switch (mcv) { | ||
| 11999 | .none => try dwarf.genVarDebugInfo(var_tag, name, ty, .empty), | ||
| 12000 | .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable, | 12076 | .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable, |
| 12001 | .immediate => |immediate| try dwarf.genVarDebugInfo(var_tag, name, ty, .{ .stack_value = &.{ | 12077 | .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, Immediate.u(imm)), |
| 12002 | .constu = immediate, | 12078 | .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr), |
| 12003 | } }), | 12079 | .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, Immediate.rel(sym_off)), |
| 12004 | else => { | 12080 | else => { |
| 12081 | const ty = switch (tag) { | ||
| 12082 | else => unreachable, | ||
| 12083 | .arg => self.typeOfIndex(inst), | ||
| 12084 | .dbg_arg_inline, .dbg_var_val => self.typeOf( | ||
| 12085 | self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op.operand, | ||
| 12086 | ), | ||
| 12087 | }; | ||
| 12005 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, self.pt)); | 12088 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, self.pt)); |
| 12006 | try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{}); | 12089 | try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{}); |
| 12007 | try stack_vars.append(self.gpa, .{ | 12090 | try self.asmAirMemory(.dbg_local, inst, .{ |
| 12008 | .name = name, | 12091 | .base = .{ .frame = frame_index }, |
| 12009 | .type = ty, | 12092 | .mod = .{ .rm = .{ .size = .qword } }, |
| 12010 | .frame_addr = .{ .index = frame_index }, | ||
| 12011 | }); | 12093 | }); |
| 12012 | }, | 12094 | }, |
| 12013 | }, | 12095 | } |
| 12014 | }, | 12096 | }, |
| 12015 | .plan9 => {}, | 12097 | .dbg_var_ptr => switch (mcv) { |
| 12016 | .none => {}, | 12098 | else => unreachable, |
| 12017 | } | 12099 | .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable, |
| 12018 | } | 12100 | .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{ |
| 12019 | 12101 | .base = .{ .frame = frame_addr.index }, | |
| 12020 | fn genStackVarDebugInfo( | 12102 | .mod = .{ .rm = .{ |
| 12021 | self: Self, | 12103 | .size = .qword, |
| 12022 | var_tag: link.File.Dwarf.WipNav.VarTag, | 12104 | .disp = frame_addr.off, |
| 12023 | stack_vars: []const StackVar, | 12105 | } }, |
| 12024 | ) !void { | 12106 | }), |
| 12025 | switch (self.debug_output) { | 12107 | .lea_symbol => |sym_off| try self.asmAirMemory(.dbg_local, inst, .{ |
| 12026 | .dwarf => |dwarf| for (stack_vars) |stack_var| { | 12108 | .base = .{ .reloc = sym_off.sym_index }, |
| 12027 | const frame_loc = self.frame_locs.get(@intFromEnum(stack_var.frame_addr.index)); | 12109 | .mod = .{ .rm = .{ |
| 12028 | try dwarf.genVarDebugInfo(var_tag, stack_var.name, stack_var.type, .{ .plus = .{ | 12110 | .size = .qword, |
| 12029 | &.{ .breg = frame_loc.base.dwarfNum() }, | 12111 | .disp = sym_off.off, |
| 12030 | &.{ .consts = @as(i33, frame_loc.disp) + stack_var.frame_addr.off }, | 12112 | } }, |
| 12031 | } }); | 12113 | }), |
| 12114 | .lea_direct, .lea_got, .lea_tlv => |sym_index| try self.asmAirMemory(.dbg_local, inst, .{ | ||
| 12115 | .base = .{ .reloc = sym_index }, | ||
| 12116 | .mod = .{ .rm = .{ .size = .qword } }, | ||
| 12117 | }), | ||
| 12032 | }, | 12118 | }, |
| 12033 | .plan9 => {}, | ||
| 12034 | .none => {}, | ||
| 12035 | } | 12119 | } |
| 12036 | } | 12120 | } |
| 12037 | 12121 | ||
| ... | @@ -12351,10 +12435,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12351,10 +12435,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12351 | if (self.bin_file.cast(.elf)) |elf_file| { | 12435 | if (self.bin_file.cast(.elf)) |elf_file| { |
| 12352 | const zo = elf_file.zigObjectPtr().?; | 12436 | const zo = elf_file.zigObjectPtr().?; |
| 12353 | const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav); | 12437 | const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav); |
| 12354 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ | 12438 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = sym_index })); |
| 12355 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 12356 | .sym_index = sym_index, | ||
| 12357 | })); | ||
| 12358 | } else if (self.bin_file.cast(.coff)) |coff_file| { | 12439 | } else if (self.bin_file.cast(.coff)) |coff_file| { |
| 12359 | const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav); | 12440 | const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav); |
| 12360 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | 12441 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| ... | @@ -12364,10 +12445,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12364,10 +12445,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12364 | const zo = macho_file.getZigObject().?; | 12445 | const zo = macho_file.getZigObject().?; |
| 12365 | const sym_index = try zo.getOrCreateMetadataForNav(macho_file, func.owner_nav); | 12446 | const sym_index = try zo.getOrCreateMetadataForNav(macho_file, func.owner_nav); |
| 12366 | const sym = zo.symbols.items[sym_index]; | 12447 | const sym = zo.symbols.items[sym_index]; |
| 12367 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ | 12448 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = sym.nlist_idx })); |
| 12368 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 12369 | .sym_index = sym.nlist_idx, | ||
| 12370 | })); | ||
| 12371 | } else if (self.bin_file.cast(.plan9)) |p9| { | 12449 | } else if (self.bin_file.cast(.plan9)) |p9| { |
| 12372 | const atom_index = try p9.seeNav(pt, func.owner_nav); | 12450 | const atom_index = try p9.seeNav(pt, func.owner_nav); |
| 12373 | const atom = p9.getAtom(atom_index); | 12451 | const atom = p9.getAtom(atom_index); |
| ... | @@ -12385,19 +12463,13 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12385,19 +12463,13 @@ fn genCall(self: *Self, info: union(enum) { |
| 12385 | @"extern".name.toSlice(ip), | 12463 | @"extern".name.toSlice(ip), |
| 12386 | @"extern".lib_name.toSlice(ip), | 12464 | @"extern".lib_name.toSlice(ip), |
| 12387 | ); | 12465 | ); |
| 12388 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ | 12466 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = target_sym_index })); |
| 12389 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 12390 | .sym_index = target_sym_index, | ||
| 12391 | })); | ||
| 12392 | } else if (self.bin_file.cast(.macho)) |macho_file| { | 12467 | } else if (self.bin_file.cast(.macho)) |macho_file| { |
| 12393 | const target_sym_index = try macho_file.getGlobalSymbol( | 12468 | const target_sym_index = try macho_file.getGlobalSymbol( |
| 12394 | @"extern".name.toSlice(ip), | 12469 | @"extern".name.toSlice(ip), |
| 12395 | @"extern".lib_name.toSlice(ip), | 12470 | @"extern".lib_name.toSlice(ip), |
| 12396 | ); | 12471 | ); |
| 12397 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ | 12472 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = target_sym_index })); |
| 12398 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 12399 | .sym_index = target_sym_index, | ||
| 12400 | })); | ||
| 12401 | } else try self.genExternSymbolRef( | 12473 | } else try self.genExternSymbolRef( |
| 12402 | .call, | 12474 | .call, |
| 12403 | @"extern".lib_name.toSlice(ip), | 12475 | @"extern".lib_name.toSlice(ip), |
| ... | @@ -12412,16 +12484,10 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12412,16 +12484,10 @@ fn genCall(self: *Self, info: union(enum) { |
| 12412 | }, | 12484 | }, |
| 12413 | .lib => |lib| if (self.bin_file.cast(.elf)) |elf_file| { | 12485 | .lib => |lib| if (self.bin_file.cast(.elf)) |elf_file| { |
| 12414 | const target_sym_index = try elf_file.getGlobalSymbol(lib.callee, lib.lib); | 12486 | const target_sym_index = try elf_file.getGlobalSymbol(lib.callee, lib.lib); |
| 12415 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ | 12487 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = target_sym_index })); |
| 12416 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 12417 | .sym_index = target_sym_index, | ||
| 12418 | })); | ||
| 12419 | } else if (self.bin_file.cast(.macho)) |macho_file| { | 12488 | } else if (self.bin_file.cast(.macho)) |macho_file| { |
| 12420 | const target_sym_index = try macho_file.getGlobalSymbol(lib.callee, lib.lib); | 12489 | const target_sym_index = try macho_file.getGlobalSymbol(lib.callee, lib.lib); |
| 12421 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ | 12490 | try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = target_sym_index })); |
| 12422 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 12423 | .sym_index = target_sym_index, | ||
| 12424 | })); | ||
| 12425 | } else try self.genExternSymbolRef(.call, lib.lib, lib.callee), | 12491 | } else try self.genExternSymbolRef(.call, lib.lib, lib.callee), |
| 12426 | } | 12492 | } |
| 12427 | return call_info.return_value.short; | 12493 | return call_info.return_value.short; |
| ... | @@ -13060,29 +13126,21 @@ fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13060,29 +13126,21 @@ fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 13060 | self.inline_func = extra.data.func; | 13126 | self.inline_func = extra.data.func; |
| 13061 | _ = try self.addInst(.{ | 13127 | _ = try self.addInst(.{ |
| 13062 | .tag = .pseudo, | 13128 | .tag = .pseudo, |
| 13063 | .ops = .pseudo_dbg_inline_func, | 13129 | .ops = .pseudo_dbg_enter_inline_func, |
| 13064 | .data = .{ .func = extra.data.func }, | 13130 | .data = .{ .func = extra.data.func }, |
| 13065 | }); | 13131 | }); |
| 13066 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | 13132 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); |
| 13067 | _ = try self.addInst(.{ | 13133 | _ = try self.addInst(.{ |
| 13068 | .tag = .pseudo, | 13134 | .tag = .pseudo, |
| 13069 | .ops = .pseudo_dbg_inline_func, | 13135 | .ops = .pseudo_dbg_leave_inline_func, |
| 13070 | .data = .{ .func = old_inline_func }, | 13136 | .data = .{ .func = old_inline_func }, |
| 13071 | }); | 13137 | }); |
| 13072 | } | 13138 | } |
| 13073 | 13139 | ||
| 13074 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 13140 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 13075 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 13141 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 13076 | const operand = pl_op.operand; | 13142 | try self.genLocalDebugInfo(inst, try self.resolveInst(pl_op.operand)); |
| 13077 | const ty = self.typeOf(operand); | 13143 | return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none }); |
| 13078 | const mcv = try self.resolveInst(operand); | ||
| 13079 | |||
| 13080 | const name = self.air.nullTerminatedString(pl_op.payload); | ||
| 13081 | |||
| 13082 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | ||
| 13083 | try self.genVarDebugInfo(.local_var, tag, name, ty, mcv); | ||
| 13084 | |||
| 13085 | return self.finishAir(inst, .unreach, .{ operand, .none, .none }); | ||
| 13086 | } | 13144 | } |
| 13087 | 13145 | ||
| 13088 | fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { | 13146 | fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { |
| ... | @@ -14970,10 +15028,7 @@ fn genSetReg( | ... | @@ -14970,10 +15028,7 @@ fn genSetReg( |
| 14970 | .general_purpose => { | 15028 | .general_purpose => { |
| 14971 | assert(sym_off.off == 0); | 15029 | assert(sym_off.off == 0); |
| 14972 | try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(dst_reg, abi_size), .{ | 15030 | try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(dst_reg, abi_size), .{ |
| 14973 | .base = .{ .reloc = .{ | 15031 | .base = .{ .reloc = sym_off.sym_index }, |
| 14974 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 14975 | .sym_index = sym_off.sym, | ||
| 14976 | } }, | ||
| 14977 | .mod = .{ .rm = .{ | 15032 | .mod = .{ .rm = .{ |
| 14978 | .size = self.memSize(ty), | 15033 | .size = self.memSize(ty), |
| 14979 | .disp = sym_off.off, | 15034 | .disp = sym_off.off, |
| ... | @@ -14991,10 +15046,7 @@ fn genSetReg( | ... | @@ -14991,10 +15046,7 @@ fn genSetReg( |
| 14991 | .ops = .direct_reloc, | 15046 | .ops = .direct_reloc, |
| 14992 | .data = .{ .rx = .{ | 15047 | .data = .{ .rx = .{ |
| 14993 | .r1 = registerAlias(dst_reg, abi_size), | 15048 | .r1 = registerAlias(dst_reg, abi_size), |
| 14994 | .payload = try self.addExtra(bits.Symbol{ | 15049 | .payload = try self.addExtra(bits.SymbolOffset{ .sym_index = sym_index }), |
| 14995 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 14996 | .sym_index = sym_index, | ||
| 14997 | }), | ||
| 14998 | } }, | 15050 | } }, |
| 14999 | }); | 15051 | }); |
| 15000 | return; | 15052 | return; |
| ... | @@ -15019,52 +15071,38 @@ fn genSetReg( | ... | @@ -15019,52 +15071,38 @@ fn genSetReg( |
| 15019 | }, | 15071 | }, |
| 15020 | ); | 15072 | ); |
| 15021 | }, | 15073 | }, |
| 15022 | .lea_symbol => |sym_index| { | 15074 | .lea_symbol => |sym_off| switch (self.bin_file.tag) { |
| 15023 | const atom_index = try self.owner.getSymbolIndex(self); | 15075 | .elf, .macho => try self.asmRegisterMemory( |
| 15024 | switch (self.bin_file.tag) { | 15076 | .{ ._, .lea }, |
| 15025 | .elf, .macho => { | 15077 | dst_reg.to64(), |
| 15026 | try self.asmRegisterMemory( | 15078 | .{ |
| 15027 | .{ ._, .lea }, | 15079 | .base = .{ .reloc = sym_off.sym_index }, |
| 15028 | dst_reg.to64(), | 15080 | .mod = .{ .rm = .{ |
| 15029 | .{ | 15081 | .size = .qword, |
| 15030 | .base = .{ .reloc = .{ | 15082 | .disp = sym_off.off, |
| 15031 | .atom_index = atom_index, | 15083 | } }, |
| 15032 | .sym_index = sym_index.sym, | ||
| 15033 | } }, | ||
| 15034 | .mod = .{ .rm = .{ | ||
| 15035 | .size = .qword, | ||
| 15036 | .disp = sym_index.off, | ||
| 15037 | } }, | ||
| 15038 | }, | ||
| 15039 | ); | ||
| 15040 | }, | ||
| 15041 | else => return self.fail("TODO emit symbol sequence on {s}", .{ | ||
| 15042 | @tagName(self.bin_file.tag), | ||
| 15043 | }), | ||
| 15044 | } | ||
| 15045 | }, | ||
| 15046 | .lea_direct, .lea_got => |sym_index| { | ||
| 15047 | const atom_index = try self.owner.getSymbolIndex(self); | ||
| 15048 | _ = try self.addInst(.{ | ||
| 15049 | .tag = switch (src_mcv) { | ||
| 15050 | .lea_direct => .lea, | ||
| 15051 | .lea_got => .mov, | ||
| 15052 | else => unreachable, | ||
| 15053 | }, | ||
| 15054 | .ops = switch (src_mcv) { | ||
| 15055 | .lea_direct => .direct_reloc, | ||
| 15056 | .lea_got => .got_reloc, | ||
| 15057 | else => unreachable, | ||
| 15058 | }, | 15084 | }, |
| 15059 | .data = .{ .rx = .{ | 15085 | ), |
| 15060 | .r1 = dst_reg.to64(), | 15086 | else => return self.fail("TODO emit symbol sequence on {s}", .{ |
| 15061 | .payload = try self.addExtra(bits.Symbol{ | 15087 | @tagName(self.bin_file.tag), |
| 15062 | .atom_index = atom_index, | 15088 | }), |
| 15063 | .sym_index = sym_index, | ||
| 15064 | }), | ||
| 15065 | } }, | ||
| 15066 | }); | ||
| 15067 | }, | 15089 | }, |
| 15090 | .lea_direct, .lea_got => |sym_index| _ = try self.addInst(.{ | ||
| 15091 | .tag = switch (src_mcv) { | ||
| 15092 | .lea_direct => .lea, | ||
| 15093 | .lea_got => .mov, | ||
| 15094 | else => unreachable, | ||
| 15095 | }, | ||
| 15096 | .ops = switch (src_mcv) { | ||
| 15097 | .lea_direct => .direct_reloc, | ||
| 15098 | .lea_got => .got_reloc, | ||
| 15099 | else => unreachable, | ||
| 15100 | }, | ||
| 15101 | .data = .{ .rx = .{ | ||
| 15102 | .r1 = dst_reg.to64(), | ||
| 15103 | .payload = try self.addExtra(bits.SymbolOffset{ .sym_index = sym_index }), | ||
| 15104 | } }, | ||
| 15105 | }), | ||
| 15068 | .lea_tlv => unreachable, // TODO: remove this | 15106 | .lea_tlv => unreachable, // TODO: remove this |
| 15069 | .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref), opts), | 15107 | .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref), opts), |
| 15070 | } | 15108 | } |
| ... | @@ -15085,7 +15123,7 @@ fn genSetMem( | ... | @@ -15085,7 +15123,7 @@ fn genSetMem( |
| 15085 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, | 15123 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, |
| 15086 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, | 15124 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| 15087 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, | 15125 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, |
| 15088 | .reloc => |base_symbol| .{ .lea_symbol = .{ .sym = base_symbol.sym_index, .off = disp } }, | 15126 | .reloc => |sym_index| .{ .lea_symbol = .{ .sym_index = sym_index, .off = disp } }, |
| 15089 | }; | 15127 | }; |
| 15090 | switch (src_mcv) { | 15128 | switch (src_mcv) { |
| 15091 | .none, | 15129 | .none, |
| ... | @@ -15328,7 +15366,6 @@ fn genExternSymbolRef( | ... | @@ -15328,7 +15366,6 @@ fn genExternSymbolRef( |
| 15328 | lib: ?[]const u8, | 15366 | lib: ?[]const u8, |
| 15329 | callee: []const u8, | 15367 | callee: []const u8, |
| 15330 | ) InnerError!void { | 15368 | ) InnerError!void { |
| 15331 | const atom_index = try self.owner.getSymbolIndex(self); | ||
| 15332 | if (self.bin_file.cast(.coff)) |coff_file| { | 15369 | if (self.bin_file.cast(.coff)) |coff_file| { |
| 15333 | const global_index = try coff_file.getGlobalSymbol(callee, lib); | 15370 | const global_index = try coff_file.getGlobalSymbol(callee, lib); |
| 15334 | _ = try self.addInst(.{ | 15371 | _ = try self.addInst(.{ |
| ... | @@ -15336,8 +15373,7 @@ fn genExternSymbolRef( | ... | @@ -15336,8 +15373,7 @@ fn genExternSymbolRef( |
| 15336 | .ops = .import_reloc, | 15373 | .ops = .import_reloc, |
| 15337 | .data = .{ .rx = .{ | 15374 | .data = .{ .rx = .{ |
| 15338 | .r1 = .rax, | 15375 | .r1 = .rax, |
| 15339 | .payload = try self.addExtra(bits.Symbol{ | 15376 | .payload = try self.addExtra(bits.SymbolOffset{ |
| 15340 | .atom_index = atom_index, | ||
| 15341 | .sym_index = link.File.Coff.global_symbol_bit | global_index, | 15377 | .sym_index = link.File.Coff.global_symbol_bit | global_index, |
| 15342 | }), | 15378 | }), |
| 15343 | } }, | 15379 | } }, |
| ... | @@ -15364,10 +15400,10 @@ fn genLazySymbolRef( | ... | @@ -15364,10 +15400,10 @@ fn genLazySymbolRef( |
| 15364 | if (self.mod.pic) { | 15400 | if (self.mod.pic) { |
| 15365 | switch (tag) { | 15401 | switch (tag) { |
| 15366 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ | 15402 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ |
| 15367 | .lea_symbol = .{ .sym = sym_index }, | 15403 | .lea_symbol = .{ .sym_index = sym_index }, |
| 15368 | }, .{}), | 15404 | }, .{}), |
| 15369 | .mov => try self.genSetReg(reg, Type.usize, .{ | 15405 | .mov => try self.genSetReg(reg, Type.usize, .{ |
| 15370 | .load_symbol = .{ .sym = sym_index }, | 15406 | .load_symbol = .{ .sym_index = sym_index }, |
| 15371 | }, .{}), | 15407 | }, .{}), |
| 15372 | else => unreachable, | 15408 | else => unreachable, |
| 15373 | } | 15409 | } |
| ... | @@ -15376,19 +15412,13 @@ fn genLazySymbolRef( | ... | @@ -15376,19 +15412,13 @@ fn genLazySymbolRef( |
| 15376 | .call => try self.asmRegister(.{ ._, .call }, reg), | 15412 | .call => try self.asmRegister(.{ ._, .call }, reg), |
| 15377 | else => unreachable, | 15413 | else => unreachable, |
| 15378 | } | 15414 | } |
| 15379 | } else { | 15415 | } else switch (tag) { |
| 15380 | const reloc = bits.Symbol{ | 15416 | .lea, .mov => try self.asmRegisterMemory(.{ ._, tag }, reg.to64(), .{ |
| 15381 | .atom_index = try self.owner.getSymbolIndex(self), | 15417 | .base = .{ .reloc = sym_index }, |
| 15382 | .sym_index = sym_index, | 15418 | .mod = .{ .rm = .{ .size = .qword } }, |
| 15383 | }; | 15419 | }), |
| 15384 | switch (tag) { | 15420 | .call => try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = sym_index })), |
| 15385 | .lea, .mov => try self.asmRegisterMemory(.{ ._, tag }, reg.to64(), .{ | 15421 | else => unreachable, |
| 15386 | .base = .{ .reloc = reloc }, | ||
| 15387 | .mod = .{ .rm = .{ .size = .qword } }, | ||
| 15388 | }), | ||
| 15389 | .call => try self.asmImmediate(.{ ._, .call }, Immediate.rel(reloc)), | ||
| 15390 | else => unreachable, | ||
| 15391 | } | ||
| 15392 | } | 15422 | } |
| 15393 | } else if (self.bin_file.cast(.plan9)) |p9_file| { | 15423 | } else if (self.bin_file.cast(.plan9)) |p9_file| { |
| 15394 | const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err| | 15424 | const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err| |
| ... | @@ -15438,10 +15468,10 @@ fn genLazySymbolRef( | ... | @@ -15438,10 +15468,10 @@ fn genLazySymbolRef( |
| 15438 | const sym = zo.symbols.items[sym_index]; | 15468 | const sym = zo.symbols.items[sym_index]; |
| 15439 | switch (tag) { | 15469 | switch (tag) { |
| 15440 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ | 15470 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ |
| 15441 | .lea_symbol = .{ .sym = sym.nlist_idx }, | 15471 | .lea_symbol = .{ .sym_index = sym.nlist_idx }, |
| 15442 | }, .{}), | 15472 | }, .{}), |
| 15443 | .mov => try self.genSetReg(reg, Type.usize, .{ | 15473 | .mov => try self.genSetReg(reg, Type.usize, .{ |
| 15444 | .load_symbol = .{ .sym = sym.nlist_idx }, | 15474 | .load_symbol = .{ .sym_index = sym.nlist_idx }, |
| 15445 | }, .{}), | 15475 | }, .{}), |
| 15446 | else => unreachable, | 15476 | else => unreachable, |
| 15447 | } | 15477 | } |
| ... | @@ -18786,7 +18816,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -18786,7 +18816,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 18786 | .{ .frame = frame_index }, | 18816 | .{ .frame = frame_index }, |
| 18787 | 0, | 18817 | 0, |
| 18788 | Type.usize, | 18818 | Type.usize, |
| 18789 | .{ .lea_symbol = .{ .sym = tlv_sym } }, | 18819 | .{ .lea_symbol = .{ .sym_index = tlv_sym } }, |
| 18790 | .{}, | 18820 | .{}, |
| 18791 | ); | 18821 | ); |
| 18792 | break :init .{ .load_frame = .{ .index = frame_index } }; | 18822 | break :init .{ .load_frame = .{ .index = frame_index } }; |
| ... | @@ -18842,8 +18872,8 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { | ... | @@ -18842,8 +18872,8 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 18842 | .undef => .undef, | 18872 | .undef => .undef, |
| 18843 | .immediate => |imm| .{ .immediate = imm }, | 18873 | .immediate => |imm| .{ .immediate = imm }, |
| 18844 | .memory => |addr| .{ .memory = addr }, | 18874 | .memory => |addr| .{ .memory = addr }, |
| 18845 | .load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } }, | 18875 | .load_symbol => |sym_index| .{ .load_symbol = .{ .sym_index = sym_index } }, |
| 18846 | .lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym = sym_index } }, | 18876 | .lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym_index = sym_index } }, |
| 18847 | .load_direct => |sym_index| .{ .load_direct = sym_index }, | 18877 | .load_direct => |sym_index| .{ .load_direct = sym_index }, |
| 18848 | .lea_direct => |sym_index| .{ .lea_direct = sym_index }, | 18878 | .lea_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 18849 | .load_got => |sym_index| .{ .lea_got = sym_index }, | 18879 | .load_got => |sym_index| .{ .lea_got = sym_index }, |
src/arch/x86_64/Emit.zig+195-52| ... | @@ -1,6 +1,8 @@ | ... | @@ -1,6 +1,8 @@ |
| 1 | //! This file contains the functionality for emitting x86_64 MIR as machine code | 1 | //! This file contains the functionality for emitting x86_64 MIR as machine code |
| 2 | 2 | ||
| 3 | air: Air, | ||
| 3 | lower: Lower, | 4 | lower: Lower, |
| 5 | atom_index: u32, | ||
| 4 | debug_output: DebugInfoOutput, | 6 | debug_output: DebugInfoOutput, |
| 5 | code: *std.ArrayList(u8), | 7 | code: *std.ArrayList(u8), |
| 6 | 8 | ||
| ... | @@ -36,83 +38,84 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -36,83 +38,84 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 36 | }) switch (lowered_relocs[0].target) { | 38 | }) switch (lowered_relocs[0].target) { |
| 37 | .inst => |target| try emit.relocs.append(emit.lower.allocator, .{ | 39 | .inst => |target| try emit.relocs.append(emit.lower.allocator, .{ |
| 38 | .source = start_offset, | 40 | .source = start_offset, |
| 41 | .source_offset = end_offset - 4, | ||
| 39 | .target = target, | 42 | .target = target, |
| 40 | .offset = end_offset - 4, | 43 | .target_offset = lowered_relocs[0].off, |
| 41 | .length = @intCast(end_offset - start_offset), | 44 | .length = @intCast(end_offset - start_offset), |
| 42 | }), | 45 | }), |
| 43 | .linker_extern_fn => |symbol| if (emit.lower.bin_file.cast(.elf)) |elf_file| { | 46 | .linker_extern_fn => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| { |
| 44 | // Add relocation to the decl. | 47 | // Add relocation to the decl. |
| 45 | const zo = elf_file.zigObjectPtr().?; | 48 | const zo = elf_file.zigObjectPtr().?; |
| 46 | const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?; | 49 | const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?; |
| 47 | const r_type = @intFromEnum(std.elf.R_X86_64.PLT32); | 50 | const r_type = @intFromEnum(std.elf.R_X86_64.PLT32); |
| 48 | try atom_ptr.addReloc(elf_file, .{ | 51 | try atom_ptr.addReloc(elf_file, .{ |
| 49 | .r_offset = end_offset - 4, | 52 | .r_offset = end_offset - 4, |
| 50 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type, | 53 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 51 | .r_addend = -4, | 54 | .r_addend = lowered_relocs[0].off - 4, |
| 52 | }); | 55 | }); |
| 53 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { | 56 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { |
| 54 | // Add relocation to the decl. | 57 | // Add relocation to the decl. |
| 55 | const zo = macho_file.getZigObject().?; | 58 | const zo = macho_file.getZigObject().?; |
| 56 | const atom = zo.symbols.items[symbol.atom_index].getAtom(macho_file).?; | 59 | const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?; |
| 57 | try atom.addReloc(macho_file, .{ | 60 | try atom.addReloc(macho_file, .{ |
| 58 | .tag = .@"extern", | 61 | .tag = .@"extern", |
| 59 | .offset = end_offset - 4, | 62 | .offset = end_offset - 4, |
| 60 | .target = symbol.sym_index, | 63 | .target = sym_index, |
| 61 | .addend = 0, | 64 | .addend = lowered_relocs[0].off, |
| 62 | .type = .branch, | 65 | .type = .branch, |
| 63 | .meta = .{ | 66 | .meta = .{ |
| 64 | .pcrel = true, | 67 | .pcrel = true, |
| 65 | .has_subtractor = false, | 68 | .has_subtractor = false, |
| 66 | .length = 2, | 69 | .length = 2, |
| 67 | .symbolnum = @intCast(symbol.sym_index), | 70 | .symbolnum = @intCast(sym_index), |
| 68 | }, | 71 | }, |
| 69 | }); | 72 | }); |
| 70 | } else if (emit.lower.bin_file.cast(.coff)) |coff_file| { | 73 | } else if (emit.lower.bin_file.cast(.coff)) |coff_file| { |
| 71 | // Add relocation to the decl. | 74 | // Add relocation to the decl. |
| 72 | const atom_index = coff_file.getAtomIndexForSymbol( | 75 | const atom_index = coff_file.getAtomIndexForSymbol( |
| 73 | .{ .sym_index = symbol.atom_index, .file = null }, | 76 | .{ .sym_index = emit.atom_index, .file = null }, |
| 74 | ).?; | 77 | ).?; |
| 75 | const target = if (link.File.Coff.global_symbol_bit & symbol.sym_index != 0) | 78 | const target = if (link.File.Coff.global_symbol_bit & sym_index != 0) |
| 76 | coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & symbol.sym_index) | 79 | coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & sym_index) |
| 77 | else | 80 | else |
| 78 | link.File.Coff.SymbolWithLoc{ .sym_index = symbol.sym_index, .file = null }; | 81 | link.File.Coff.SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 79 | try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ | 82 | try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ |
| 80 | .type = .direct, | 83 | .type = .direct, |
| 81 | .target = target, | 84 | .target = target, |
| 82 | .offset = end_offset - 4, | 85 | .offset = end_offset - 4, |
| 83 | .addend = 0, | 86 | .addend = @intCast(lowered_relocs[0].off), |
| 84 | .pcrel = true, | 87 | .pcrel = true, |
| 85 | .length = 2, | 88 | .length = 2, |
| 86 | }); | 89 | }); |
| 87 | } else return emit.fail("TODO implement extern reloc for {s}", .{ | 90 | } else return emit.fail("TODO implement extern reloc for {s}", .{ |
| 88 | @tagName(emit.lower.bin_file.tag), | 91 | @tagName(emit.lower.bin_file.tag), |
| 89 | }), | 92 | }), |
| 90 | .linker_tlsld => |data| { | 93 | .linker_tlsld => |sym_index| { |
| 91 | const elf_file = emit.lower.bin_file.cast(.elf).?; | 94 | const elf_file = emit.lower.bin_file.cast(.elf).?; |
| 92 | const zo = elf_file.zigObjectPtr().?; | 95 | const zo = elf_file.zigObjectPtr().?; |
| 93 | const atom = zo.symbol(data.atom_index).atom(elf_file).?; | 96 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; |
| 94 | const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD); | 97 | const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD); |
| 95 | try atom.addReloc(elf_file, .{ | 98 | try atom.addReloc(elf_file, .{ |
| 96 | .r_offset = end_offset - 4, | 99 | .r_offset = end_offset - 4, |
| 97 | .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, | 100 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 98 | .r_addend = -4, | 101 | .r_addend = lowered_relocs[0].off - 4, |
| 99 | }); | 102 | }); |
| 100 | }, | 103 | }, |
| 101 | .linker_dtpoff => |data| { | 104 | .linker_dtpoff => |sym_index| { |
| 102 | const elf_file = emit.lower.bin_file.cast(.elf).?; | 105 | const elf_file = emit.lower.bin_file.cast(.elf).?; |
| 103 | const zo = elf_file.zigObjectPtr().?; | 106 | const zo = elf_file.zigObjectPtr().?; |
| 104 | const atom = zo.symbol(data.atom_index).atom(elf_file).?; | 107 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; |
| 105 | const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32); | 108 | const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32); |
| 106 | try atom.addReloc(elf_file, .{ | 109 | try atom.addReloc(elf_file, .{ |
| 107 | .r_offset = end_offset - 4, | 110 | .r_offset = end_offset - 4, |
| 108 | .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, | 111 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 109 | .r_addend = 0, | 112 | .r_addend = lowered_relocs[0].off, |
| 110 | }); | 113 | }); |
| 111 | }, | 114 | }, |
| 112 | .linker_reloc => |data| if (emit.lower.bin_file.cast(.elf)) |elf_file| { | 115 | .linker_reloc => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| { |
| 113 | const zo = elf_file.zigObjectPtr().?; | 116 | const zo = elf_file.zigObjectPtr().?; |
| 114 | const atom = zo.symbol(data.atom_index).atom(elf_file).?; | 117 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; |
| 115 | const sym = zo.symbol(data.sym_index); | 118 | const sym = zo.symbol(sym_index); |
| 116 | if (emit.lower.pic) { | 119 | if (emit.lower.pic) { |
| 117 | const r_type: u32 = if (sym.flags.is_extern_ptr) | 120 | const r_type: u32 = if (sym.flags.is_extern_ptr) |
| 118 | @intFromEnum(std.elf.R_X86_64.GOTPCREL) | 121 | @intFromEnum(std.elf.R_X86_64.GOTPCREL) |
| ... | @@ -120,8 +123,8 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -120,8 +123,8 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 120 | @intFromEnum(std.elf.R_X86_64.PC32); | 123 | @intFromEnum(std.elf.R_X86_64.PC32); |
| 121 | try atom.addReloc(elf_file, .{ | 124 | try atom.addReloc(elf_file, .{ |
| 122 | .r_offset = end_offset - 4, | 125 | .r_offset = end_offset - 4, |
| 123 | .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, | 126 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 124 | .r_addend = -4, | 127 | .r_addend = lowered_relocs[0].off - 4, |
| 125 | }); | 128 | }); |
| 126 | } else { | 129 | } else { |
| 127 | const r_type: u32 = if (sym.flags.is_tls) | 130 | const r_type: u32 = if (sym.flags.is_tls) |
| ... | @@ -130,14 +133,14 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -130,14 +133,14 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 130 | @intFromEnum(std.elf.R_X86_64.@"32"); | 133 | @intFromEnum(std.elf.R_X86_64.@"32"); |
| 131 | try atom.addReloc(elf_file, .{ | 134 | try atom.addReloc(elf_file, .{ |
| 132 | .r_offset = end_offset - 4, | 135 | .r_offset = end_offset - 4, |
| 133 | .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, | 136 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 134 | .r_addend = 0, | 137 | .r_addend = lowered_relocs[0].off, |
| 135 | }); | 138 | }); |
| 136 | } | 139 | } |
| 137 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { | 140 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { |
| 138 | const zo = macho_file.getZigObject().?; | 141 | const zo = macho_file.getZigObject().?; |
| 139 | const atom = zo.symbols.items[data.atom_index].getAtom(macho_file).?; | 142 | const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?; |
| 140 | const sym = &zo.symbols.items[data.sym_index]; | 143 | const sym = &zo.symbols.items[sym_index]; |
| 141 | const @"type": link.File.MachO.Relocation.Type = if (sym.flags.is_extern_ptr) | 144 | const @"type": link.File.MachO.Relocation.Type = if (sym.flags.is_extern_ptr) |
| 142 | .got_load | 145 | .got_load |
| 143 | else if (sym.flags.tlv) | 146 | else if (sym.flags.tlv) |
| ... | @@ -147,33 +150,33 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -147,33 +150,33 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 147 | try atom.addReloc(macho_file, .{ | 150 | try atom.addReloc(macho_file, .{ |
| 148 | .tag = .@"extern", | 151 | .tag = .@"extern", |
| 149 | .offset = @intCast(end_offset - 4), | 152 | .offset = @intCast(end_offset - 4), |
| 150 | .target = data.sym_index, | 153 | .target = sym_index, |
| 151 | .addend = 0, | 154 | .addend = lowered_relocs[0].off, |
| 152 | .type = @"type", | 155 | .type = @"type", |
| 153 | .meta = .{ | 156 | .meta = .{ |
| 154 | .pcrel = true, | 157 | .pcrel = true, |
| 155 | .has_subtractor = false, | 158 | .has_subtractor = false, |
| 156 | .length = 2, | 159 | .length = 2, |
| 157 | .symbolnum = @intCast(data.sym_index), | 160 | .symbolnum = @intCast(sym_index), |
| 158 | }, | 161 | }, |
| 159 | }); | 162 | }); |
| 160 | } else unreachable, | 163 | } else unreachable, |
| 161 | .linker_got, | 164 | .linker_got, |
| 162 | .linker_direct, | 165 | .linker_direct, |
| 163 | .linker_import, | 166 | .linker_import, |
| 164 | => |symbol| if (emit.lower.bin_file.cast(.elf)) |_| { | 167 | => |sym_index| if (emit.lower.bin_file.cast(.elf)) |_| { |
| 165 | unreachable; | 168 | unreachable; |
| 166 | } else if (emit.lower.bin_file.cast(.macho)) |_| { | 169 | } else if (emit.lower.bin_file.cast(.macho)) |_| { |
| 167 | unreachable; | 170 | unreachable; |
| 168 | } else if (emit.lower.bin_file.cast(.coff)) |coff_file| { | 171 | } else if (emit.lower.bin_file.cast(.coff)) |coff_file| { |
| 169 | const atom_index = coff_file.getAtomIndexForSymbol(.{ | 172 | const atom_index = coff_file.getAtomIndexForSymbol(.{ |
| 170 | .sym_index = symbol.atom_index, | 173 | .sym_index = emit.atom_index, |
| 171 | .file = null, | 174 | .file = null, |
| 172 | }).?; | 175 | }).?; |
| 173 | const target = if (link.File.Coff.global_symbol_bit & symbol.sym_index != 0) | 176 | const target = if (link.File.Coff.global_symbol_bit & sym_index != 0) |
| 174 | coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & symbol.sym_index) | 177 | coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & sym_index) |
| 175 | else | 178 | else |
| 176 | link.File.Coff.SymbolWithLoc{ .sym_index = symbol.sym_index, .file = null }; | 179 | link.File.Coff.SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 177 | try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ | 180 | try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ |
| 178 | .type = switch (lowered_relocs[0].target) { | 181 | .type = switch (lowered_relocs[0].target) { |
| 179 | .linker_got => .got, | 182 | .linker_got => .got, |
| ... | @@ -183,16 +186,15 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -183,16 +186,15 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 183 | }, | 186 | }, |
| 184 | .target = target, | 187 | .target = target, |
| 185 | .offset = @intCast(end_offset - 4), | 188 | .offset = @intCast(end_offset - 4), |
| 186 | .addend = 0, | 189 | .addend = @intCast(lowered_relocs[0].off), |
| 187 | .pcrel = true, | 190 | .pcrel = true, |
| 188 | .length = 2, | 191 | .length = 2, |
| 189 | }); | 192 | }); |
| 190 | } else if (emit.lower.bin_file.cast(.plan9)) |p9_file| { | 193 | } else if (emit.lower.bin_file.cast(.plan9)) |p9_file| { |
| 191 | const atom_index = symbol.atom_index; | 194 | try p9_file.addReloc(emit.atom_index, .{ // TODO we may need to add a .type field to the relocs if they are .linker_got instead of just .linker_direct |
| 192 | try p9_file.addReloc(atom_index, .{ // TODO we may need to add a .type field to the relocs if they are .linker_got instead of just .linker_direct | 195 | .target = sym_index, // we set sym_index to just be the atom index |
| 193 | .target = symbol.sym_index, // we set sym_index to just be the atom index | ||
| 194 | .offset = @intCast(end_offset - 4), | 196 | .offset = @intCast(end_offset - 4), |
| 195 | .addend = 0, | 197 | .addend = @intCast(lowered_relocs[0].off), |
| 196 | .type = .pcrel, | 198 | .type = .pcrel, |
| 197 | }); | 199 | }); |
| 198 | } else return emit.fail("TODO implement linker reloc for {s}", .{ | 200 | } else return emit.fail("TODO implement linker reloc for {s}", .{ |
| ... | @@ -232,13 +234,151 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -232,13 +234,151 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 232 | .none => {}, | 234 | .none => {}, |
| 233 | } | 235 | } |
| 234 | }, | 236 | }, |
| 235 | .pseudo_dbg_inline_func => { | 237 | .pseudo_dbg_enter_inline_func => { |
| 236 | switch (emit.debug_output) { | 238 | switch (emit.debug_output) { |
| 237 | .dwarf => |dw| { | 239 | .dwarf => |dw| { |
| 238 | log.debug("mirDbgInline (line={d}, col={d})", .{ | 240 | log.debug("mirDbgEnterInline (line={d}, col={d})", .{ |
| 239 | emit.prev_di_line, emit.prev_di_column, | 241 | emit.prev_di_line, emit.prev_di_column, |
| 240 | }); | 242 | }); |
| 241 | try dw.setInlineFunc(mir_inst.data.func); | 243 | try dw.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_line, emit.prev_di_column); |
| 244 | }, | ||
| 245 | .plan9 => {}, | ||
| 246 | .none => {}, | ||
| 247 | } | ||
| 248 | }, | ||
| 249 | .pseudo_dbg_leave_inline_func => { | ||
| 250 | switch (emit.debug_output) { | ||
| 251 | .dwarf => |dw| { | ||
| 252 | log.debug("mirDbgLeaveInline (line={d}, col={d})", .{ | ||
| 253 | emit.prev_di_line, emit.prev_di_column, | ||
| 254 | }); | ||
| 255 | try dw.leaveInlineFunc(mir_inst.data.func, emit.code.items.len); | ||
| 256 | }, | ||
| 257 | .plan9 => {}, | ||
| 258 | .none => {}, | ||
| 259 | } | ||
| 260 | }, | ||
| 261 | .pseudo_dbg_local_a, | ||
| 262 | .pseudo_dbg_local_ai_s, | ||
| 263 | .pseudo_dbg_local_ai_u, | ||
| 264 | .pseudo_dbg_local_ai_64, | ||
| 265 | .pseudo_dbg_local_as, | ||
| 266 | .pseudo_dbg_local_aso, | ||
| 267 | .pseudo_dbg_local_aro, | ||
| 268 | .pseudo_dbg_local_af, | ||
| 269 | .pseudo_dbg_local_am, | ||
| 270 | => { | ||
| 271 | switch (emit.debug_output) { | ||
| 272 | .dwarf => |dw| { | ||
| 273 | var loc_buf: [2]link.File.Dwarf.Loc = undefined; | ||
| 274 | const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) { | ||
| 275 | else => unreachable, | ||
| 276 | .pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty }, | ||
| 277 | .pseudo_dbg_local_ai_s, | ||
| 278 | .pseudo_dbg_local_ai_u, | ||
| 279 | .pseudo_dbg_local_ai_64, | ||
| 280 | => .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: { | ||
| 281 | loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) { | ||
| 282 | .signed => |s| .{ .consts = s }, | ||
| 283 | .unsigned => |u| .{ .constu = u }, | ||
| 284 | }; | ||
| 285 | break :stack_value &loc_buf[0]; | ||
| 286 | } } }, | ||
| 287 | .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{ .addr = .{ | ||
| 288 | .sym = mir_inst.data.as.sym_index, | ||
| 289 | } } }, | ||
| 290 | .pseudo_dbg_local_aso => loc: { | ||
| 291 | const sym_off = emit.lower.mir.extraData( | ||
| 292 | bits.SymbolOffset, | ||
| 293 | mir_inst.data.ax.payload, | ||
| 294 | ).data; | ||
| 295 | break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{ | ||
| 296 | sym: { | ||
| 297 | loc_buf[0] = .{ .addr = .{ .sym = sym_off.sym_index } }; | ||
| 298 | break :sym &loc_buf[0]; | ||
| 299 | }, | ||
| 300 | off: { | ||
| 301 | loc_buf[1] = .{ .consts = sym_off.off }; | ||
| 302 | break :off &loc_buf[1]; | ||
| 303 | }, | ||
| 304 | } } }; | ||
| 305 | }, | ||
| 306 | .pseudo_dbg_local_aro => loc: { | ||
| 307 | const air_off = emit.lower.mir.extraData( | ||
| 308 | Mir.AirOffset, | ||
| 309 | mir_inst.data.rx.payload, | ||
| 310 | ).data; | ||
| 311 | break :loc .{ air_off.air_inst, .{ .plus = .{ | ||
| 312 | reg: { | ||
| 313 | loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() }; | ||
| 314 | break :reg &loc_buf[0]; | ||
| 315 | }, | ||
| 316 | off: { | ||
| 317 | loc_buf[1] = .{ .consts = air_off.off }; | ||
| 318 | break :off &loc_buf[1]; | ||
| 319 | }, | ||
| 320 | } } }; | ||
| 321 | }, | ||
| 322 | .pseudo_dbg_local_af => loc: { | ||
| 323 | const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData( | ||
| 324 | bits.FrameAddr, | ||
| 325 | mir_inst.data.ax.payload, | ||
| 326 | ).data); | ||
| 327 | break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{ | ||
| 328 | reg: { | ||
| 329 | loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() }; | ||
| 330 | break :reg &loc_buf[0]; | ||
| 331 | }, | ||
| 332 | off: { | ||
| 333 | loc_buf[1] = .{ .consts = reg_off.off }; | ||
| 334 | break :off &loc_buf[1]; | ||
| 335 | }, | ||
| 336 | } } }; | ||
| 337 | }, | ||
| 338 | .pseudo_dbg_local_am => loc: { | ||
| 339 | const mem = emit.lower.mem(mir_inst.data.ax.payload); | ||
| 340 | break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{ | ||
| 341 | base: { | ||
| 342 | loc_buf[0] = switch (mem.base()) { | ||
| 343 | .none => .{ .constu = 0 }, | ||
| 344 | .reg => |reg| .{ .breg = reg.dwarfNum() }, | ||
| 345 | .frame => unreachable, | ||
| 346 | .reloc => |sym_index| .{ .addr = .{ .sym = sym_index } }, | ||
| 347 | }; | ||
| 348 | break :base &loc_buf[0]; | ||
| 349 | }, | ||
| 350 | disp: { | ||
| 351 | loc_buf[1] = switch (mem.disp()) { | ||
| 352 | .signed => |s| .{ .consts = s }, | ||
| 353 | .unsigned => |u| .{ .constu = u }, | ||
| 354 | }; | ||
| 355 | break :disp &loc_buf[1]; | ||
| 356 | }, | ||
| 357 | } } }; | ||
| 358 | }, | ||
| 359 | }; | ||
| 360 | const ip = &emit.lower.bin_file.comp.module.?.intern_pool; | ||
| 361 | const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index)); | ||
| 362 | const name: Air.NullTerminatedString = switch (air_inst.tag) { | ||
| 363 | else => unreachable, | ||
| 364 | .arg => air_inst.data.arg.name, | ||
| 365 | .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload), | ||
| 366 | }; | ||
| 367 | try dw.genLocalDebugInfo( | ||
| 368 | switch (air_inst.tag) { | ||
| 369 | else => unreachable, | ||
| 370 | .arg, .dbg_arg_inline => .local_arg, | ||
| 371 | .dbg_var_ptr, .dbg_var_val => .local_var, | ||
| 372 | }, | ||
| 373 | name.toSlice(emit.air), | ||
| 374 | switch (air_inst.tag) { | ||
| 375 | else => unreachable, | ||
| 376 | .arg => emit.air.typeOfIndex(air_inst_index, ip), | ||
| 377 | .dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip), | ||
| 378 | .dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip), | ||
| 379 | }, | ||
| 380 | loc, | ||
| 381 | ); | ||
| 242 | }, | 382 | }, |
| 243 | .plan9 => {}, | 383 | .plan9 => {}, |
| 244 | .none => {}, | 384 | .none => {}, |
| ... | @@ -268,10 +408,12 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error { | ... | @@ -268,10 +408,12 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error { |
| 268 | const Reloc = struct { | 408 | const Reloc = struct { |
| 269 | /// Offset of the instruction. | 409 | /// Offset of the instruction. |
| 270 | source: usize, | 410 | source: usize, |
| 411 | /// Offset of the relocation within the instruction. | ||
| 412 | source_offset: u32, | ||
| 271 | /// Target of the relocation. | 413 | /// Target of the relocation. |
| 272 | target: Mir.Inst.Index, | 414 | target: Mir.Inst.Index, |
| 273 | /// Offset of the relocation within the instruction. | 415 | /// Offset from the target instruction. |
| 274 | offset: u32, | 416 | target_offset: i32, |
| 275 | /// Length of the instruction. | 417 | /// Length of the instruction. |
| 276 | length: u5, | 418 | length: u5, |
| 277 | }; | 419 | }; |
| ... | @@ -284,8 +426,8 @@ fn fixupRelocs(emit: *Emit) Error!void { | ... | @@ -284,8 +426,8 @@ fn fixupRelocs(emit: *Emit) Error!void { |
| 284 | for (emit.relocs.items) |reloc| { | 426 | for (emit.relocs.items) |reloc| { |
| 285 | const target = emit.code_offset_mapping.get(reloc.target) orelse | 427 | const target = emit.code_offset_mapping.get(reloc.target) orelse |
| 286 | return emit.fail("JMP/CALL relocation target not found!", .{}); | 428 | return emit.fail("JMP/CALL relocation target not found!", .{}); |
| 287 | const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length)); | 429 | const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length)) + reloc.target_offset; |
| 288 | mem.writeInt(i32, emit.code.items[reloc.offset..][0..4], @intCast(disp), .little); | 430 | std.mem.writeInt(i32, emit.code.items[reloc.source_offset..][0..4], @intCast(disp), .little); |
| 289 | } | 431 | } |
| 290 | } | 432 | } |
| 291 | 433 | ||
| ... | @@ -338,11 +480,12 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void { | ... | @@ -338,11 +480,12 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void { |
| 338 | } | 480 | } |
| 339 | } | 481 | } |
| 340 | 482 | ||
| 483 | const bits = @import("bits.zig"); | ||
| 341 | const link = @import("../../link.zig"); | 484 | const link = @import("../../link.zig"); |
| 342 | const log = std.log.scoped(.emit); | 485 | const log = std.log.scoped(.emit); |
| 343 | const mem = std.mem; | ||
| 344 | const std = @import("std"); | 486 | const std = @import("std"); |
| 345 | 487 | ||
| 488 | const Air = @import("../../Air.zig"); | ||
| 346 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; | 489 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; |
| 347 | const Emit = @This(); | 490 | const Emit = @This(); |
| 348 | const Lower = @import("Lower.zig"); | 491 | const Lower = @import("Lower.zig"); |
src/arch/x86_64/Lower.zig+60-52| ... | @@ -4,10 +4,10 @@ bin_file: *link.File, | ... | @@ -4,10 +4,10 @@ bin_file: *link.File, |
| 4 | output_mode: std.builtin.OutputMode, | 4 | output_mode: std.builtin.OutputMode, |
| 5 | link_mode: std.builtin.LinkMode, | 5 | link_mode: std.builtin.LinkMode, |
| 6 | pic: bool, | 6 | pic: bool, |
| 7 | allocator: Allocator, | 7 | allocator: std.mem.Allocator, |
| 8 | mir: Mir, | 8 | mir: Mir, |
| 9 | cc: std.builtin.CallingConvention, | 9 | cc: std.builtin.CallingConvention, |
| 10 | err_msg: ?*ErrorMsg = null, | 10 | err_msg: ?*Zcu.ErrorMsg = null, |
| 11 | src_loc: Zcu.LazySrcLoc, | 11 | src_loc: Zcu.LazySrcLoc, |
| 12 | result_insts_len: u8 = undefined, | 12 | result_insts_len: u8 = undefined, |
| 13 | result_relocs_len: u8 = undefined, | 13 | result_relocs_len: u8 = undefined, |
| ... | @@ -52,16 +52,17 @@ pub const Error = error{ | ... | @@ -52,16 +52,17 @@ pub const Error = error{ |
| 52 | pub const Reloc = struct { | 52 | pub const Reloc = struct { |
| 53 | lowered_inst_index: u8, | 53 | lowered_inst_index: u8, |
| 54 | target: Target, | 54 | target: Target, |
| 55 | off: i32, | ||
| 55 | 56 | ||
| 56 | const Target = union(enum) { | 57 | const Target = union(enum) { |
| 57 | inst: Mir.Inst.Index, | 58 | inst: Mir.Inst.Index, |
| 58 | linker_reloc: bits.Symbol, | 59 | linker_reloc: u32, |
| 59 | linker_tlsld: bits.Symbol, | 60 | linker_tlsld: u32, |
| 60 | linker_dtpoff: bits.Symbol, | 61 | linker_dtpoff: u32, |
| 61 | linker_extern_fn: bits.Symbol, | 62 | linker_extern_fn: u32, |
| 62 | linker_got: bits.Symbol, | 63 | linker_got: u32, |
| 63 | linker_direct: bits.Symbol, | 64 | linker_direct: u32, |
| 64 | linker_import: bits.Symbol, | 65 | linker_import: u32, |
| 65 | }; | 66 | }; |
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| ... | @@ -173,19 +174,19 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -173,19 +174,19 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 173 | .pseudo_j_z_and_np_inst => { | 174 | .pseudo_j_z_and_np_inst => { |
| 174 | assert(inst.data.inst.fixes == ._); | 175 | assert(inst.data.inst.fixes == ._); |
| 175 | try lower.emit(.none, .jnz, &.{ | 176 | try lower.emit(.none, .jnz, &.{ |
| 176 | .{ .imm = lower.reloc(.{ .inst = index + 1 }) }, | 177 | .{ .imm = lower.reloc(.{ .inst = index + 1 }, 0) }, |
| 177 | }); | 178 | }); |
| 178 | try lower.emit(.none, .jnp, &.{ | 179 | try lower.emit(.none, .jnp, &.{ |
| 179 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }) }, | 180 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, |
| 180 | }); | 181 | }); |
| 181 | }, | 182 | }, |
| 182 | .pseudo_j_nz_or_p_inst => { | 183 | .pseudo_j_nz_or_p_inst => { |
| 183 | assert(inst.data.inst.fixes == ._); | 184 | assert(inst.data.inst.fixes == ._); |
| 184 | try lower.emit(.none, .jnz, &.{ | 185 | try lower.emit(.none, .jnz, &.{ |
| 185 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }) }, | 186 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, |
| 186 | }); | 187 | }); |
| 187 | try lower.emit(.none, .jp, &.{ | 188 | try lower.emit(.none, .jp, &.{ |
| 188 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }) }, | 189 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, |
| 189 | }); | 190 | }); |
| 190 | }, | 191 | }, |
| 191 | 192 | ||
| ... | @@ -195,7 +196,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -195,7 +196,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 195 | .{ .imm = Immediate.s(@bitCast(inst.data.ri.i)) }, | 196 | .{ .imm = Immediate.s(@bitCast(inst.data.ri.i)) }, |
| 196 | }); | 197 | }); |
| 197 | try lower.emit(.none, .jz, &.{ | 198 | try lower.emit(.none, .jz, &.{ |
| 198 | .{ .imm = lower.reloc(.{ .inst = index + 1 }) }, | 199 | .{ .imm = lower.reloc(.{ .inst = index + 1 }, 0) }, |
| 199 | }); | 200 | }); |
| 200 | try lower.emit(.none, .lea, &.{ | 201 | try lower.emit(.none, .lea, &.{ |
| 201 | .{ .reg = inst.data.ri.r1 }, | 202 | .{ .reg = inst.data.ri.r1 }, |
| ... | @@ -211,7 +212,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -211,7 +212,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 211 | .{ .reg = inst.data.ri.r1.to32() }, | 212 | .{ .reg = inst.data.ri.r1.to32() }, |
| 212 | }); | 213 | }); |
| 213 | try lower.emit(.none, .jmp, &.{ | 214 | try lower.emit(.none, .jmp, &.{ |
| 214 | .{ .imm = lower.reloc(.{ .inst = index }) }, | 215 | .{ .imm = lower.reloc(.{ .inst = index }, 0) }, |
| 215 | }); | 216 | }); |
| 216 | assert(lower.result_insts_len == pseudo_probe_align_insts); | 217 | assert(lower.result_insts_len == pseudo_probe_align_insts); |
| 217 | }, | 218 | }, |
| ... | @@ -257,7 +258,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -257,7 +258,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 257 | .{ .imm = Immediate.s(page_size) }, | 258 | .{ .imm = Immediate.s(page_size) }, |
| 258 | }); | 259 | }); |
| 259 | try lower.emit(.none, .jae, &.{ | 260 | try lower.emit(.none, .jae, &.{ |
| 260 | .{ .imm = lower.reloc(.{ .inst = index }) }, | 261 | .{ .imm = lower.reloc(.{ .inst = index }, 0) }, |
| 261 | }); | 262 | }); |
| 262 | assert(lower.result_insts_len == pseudo_probe_adjust_loop_insts); | 263 | assert(lower.result_insts_len == pseudo_probe_adjust_loop_insts); |
| 263 | }, | 264 | }, |
| ... | @@ -267,7 +268,17 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -267,7 +268,17 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 267 | .pseudo_dbg_prologue_end_none, | 268 | .pseudo_dbg_prologue_end_none, |
| 268 | .pseudo_dbg_line_line_column, | 269 | .pseudo_dbg_line_line_column, |
| 269 | .pseudo_dbg_epilogue_begin_none, | 270 | .pseudo_dbg_epilogue_begin_none, |
| 270 | .pseudo_dbg_inline_func, | 271 | .pseudo_dbg_enter_inline_func, |
| 272 | .pseudo_dbg_leave_inline_func, | ||
| 273 | .pseudo_dbg_local_a, | ||
| 274 | .pseudo_dbg_local_ai_s, | ||
| 275 | .pseudo_dbg_local_ai_u, | ||
| 276 | .pseudo_dbg_local_ai_64, | ||
| 277 | .pseudo_dbg_local_as, | ||
| 278 | .pseudo_dbg_local_aso, | ||
| 279 | .pseudo_dbg_local_aro, | ||
| 280 | .pseudo_dbg_local_af, | ||
| 281 | .pseudo_dbg_local_am, | ||
| 271 | .pseudo_dead_none, | 282 | .pseudo_dead_none, |
| 272 | => {}, | 283 | => {}, |
| 273 | else => unreachable, | 284 | else => unreachable, |
| ... | @@ -283,17 +294,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -283,17 +294,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 283 | pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { | 294 | pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { |
| 284 | @setCold(true); | 295 | @setCold(true); |
| 285 | assert(lower.err_msg == null); | 296 | assert(lower.err_msg == null); |
| 286 | lower.err_msg = try ErrorMsg.create(lower.allocator, lower.src_loc, format, args); | 297 | lower.err_msg = try Zcu.ErrorMsg.create(lower.allocator, lower.src_loc, format, args); |
| 287 | return error.LowerFail; | 298 | return error.LowerFail; |
| 288 | } | 299 | } |
| 289 | 300 | ||
| 290 | fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { | 301 | pub fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { |
| 291 | return switch (ops) { | 302 | return switch (ops) { |
| 292 | .rri_s, | 303 | .rri_s, |
| 293 | .ri_s, | 304 | .ri_s, |
| 294 | .i_s, | 305 | .i_s, |
| 295 | .mi_s, | 306 | .mi_s, |
| 296 | .rmi_s, | 307 | .rmi_s, |
| 308 | .pseudo_dbg_local_ai_s, | ||
| 297 | => Immediate.s(@bitCast(i)), | 309 | => Immediate.s(@bitCast(i)), |
| 298 | 310 | ||
| 299 | .rrri, | 311 | .rrri, |
| ... | @@ -306,22 +318,26 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { | ... | @@ -306,22 +318,26 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { |
| 306 | .mri, | 318 | .mri, |
| 307 | .rrm, | 319 | .rrm, |
| 308 | .rrmi, | 320 | .rrmi, |
| 321 | .pseudo_dbg_local_ai_u, | ||
| 309 | => Immediate.u(i), | 322 | => Immediate.u(i), |
| 310 | 323 | ||
| 311 | .ri64 => Immediate.u(lower.mir.extraData(Mir.Imm64, i).data.decode()), | 324 | .ri_64, |
| 325 | .pseudo_dbg_local_ai_64, | ||
| 326 | => Immediate.u(lower.mir.extraData(Mir.Imm64, i).data.decode()), | ||
| 312 | 327 | ||
| 313 | else => unreachable, | 328 | else => unreachable, |
| 314 | }; | 329 | }; |
| 315 | } | 330 | } |
| 316 | 331 | ||
| 317 | fn mem(lower: Lower, payload: u32) Memory { | 332 | pub fn mem(lower: Lower, payload: u32) Memory { |
| 318 | return lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode(); | 333 | return lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode(); |
| 319 | } | 334 | } |
| 320 | 335 | ||
| 321 | fn reloc(lower: *Lower, target: Reloc.Target) Immediate { | 336 | fn reloc(lower: *Lower, target: Reloc.Target, off: i32) Immediate { |
| 322 | lower.result_relocs[lower.result_relocs_len] = .{ | 337 | lower.result_relocs[lower.result_relocs_len] = .{ |
| 323 | .lowered_inst_index = lower.result_insts_len, | 338 | .lowered_inst_index = lower.result_insts_len, |
| 324 | .target = target, | 339 | .target = target, |
| 340 | .off = off, | ||
| 325 | }; | 341 | }; |
| 326 | lower.result_relocs_len += 1; | 342 | lower.result_relocs_len += 1; |
| 327 | return Immediate.s(0); | 343 | return Immediate.s(0); |
| ... | @@ -337,37 +353,36 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) | ... | @@ -337,37 +353,36 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 337 | else => op, | 353 | else => op, |
| 338 | .mem => |mem_op| switch (mem_op.base()) { | 354 | .mem => |mem_op| switch (mem_op.base()) { |
| 339 | else => op, | 355 | else => op, |
| 340 | .reloc => |sym| op: { | 356 | .reloc => |sym_index| op: { |
| 341 | assert(prefix == .none); | 357 | assert(prefix == .none); |
| 342 | assert(mem_op.sib.disp == 0); | 358 | assert(mem_op.sib.disp == 0); |
| 343 | assert(mem_op.sib.scale_index.scale == 0); | 359 | assert(mem_op.sib.scale_index.scale == 0); |
| 344 | 360 | ||
| 345 | if (lower.bin_file.cast(.elf)) |elf_file| { | 361 | if (lower.bin_file.cast(.elf)) |elf_file| { |
| 346 | const zo = elf_file.zigObjectPtr().?; | 362 | const zo = elf_file.zigObjectPtr().?; |
| 347 | const elf_sym = zo.symbol(sym.sym_index); | 363 | const elf_sym = zo.symbol(sym_index); |
| 348 | 364 | ||
| 349 | if (elf_sym.flags.is_tls) { | 365 | if (elf_sym.flags.is_tls) { |
| 350 | // TODO handle extern TLS vars, i.e., emit GD model | 366 | // TODO handle extern TLS vars, i.e., emit GD model |
| 351 | if (lower.pic) { | 367 | if (lower.pic) { |
| 352 | // Here, we currently assume local dynamic TLS vars, and so | 368 | // Here, we currently assume local dynamic TLS vars, and so |
| 353 | // we emit LD model. | 369 | // we emit LD model. |
| 354 | _ = lower.reloc(.{ .linker_tlsld = sym }); | 370 | _ = lower.reloc(.{ .linker_tlsld = sym_index }, 0); |
| 355 | lower.result_insts[lower.result_insts_len] = | 371 | lower.result_insts[lower.result_insts_len] = |
| 356 | try Instruction.new(.none, .lea, &[_]Operand{ | 372 | try Instruction.new(.none, .lea, &[_]Operand{ |
| 357 | .{ .reg = .rdi }, | 373 | .{ .reg = .rdi }, |
| 358 | .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }, | 374 | .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }, |
| 359 | }); | 375 | }); |
| 360 | lower.result_insts_len += 1; | 376 | lower.result_insts_len += 1; |
| 361 | _ = lower.reloc(.{ .linker_extern_fn = .{ | 377 | _ = lower.reloc(.{ |
| 362 | .atom_index = sym.atom_index, | 378 | .linker_extern_fn = try elf_file.getGlobalSymbol("__tls_get_addr", null), |
| 363 | .sym_index = try elf_file.getGlobalSymbol("__tls_get_addr", null), | 379 | }, 0); |
| 364 | } }); | ||
| 365 | lower.result_insts[lower.result_insts_len] = | 380 | lower.result_insts[lower.result_insts_len] = |
| 366 | try Instruction.new(.none, .call, &[_]Operand{ | 381 | try Instruction.new(.none, .call, &[_]Operand{ |
| 367 | .{ .imm = Immediate.s(0) }, | 382 | .{ .imm = Immediate.s(0) }, |
| 368 | }); | 383 | }); |
| 369 | lower.result_insts_len += 1; | 384 | lower.result_insts_len += 1; |
| 370 | _ = lower.reloc(.{ .linker_dtpoff = sym }); | 385 | _ = lower.reloc(.{ .linker_dtpoff = sym_index }, 0); |
| 371 | emit_mnemonic = .lea; | 386 | emit_mnemonic = .lea; |
| 372 | break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ | 387 | break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ |
| 373 | .base = .{ .reg = .rax }, | 388 | .base = .{ .reg = .rax }, |
| ... | @@ -381,7 +396,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) | ... | @@ -381,7 +396,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 381 | .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .fs } }) }, | 396 | .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .fs } }) }, |
| 382 | }); | 397 | }); |
| 383 | lower.result_insts_len += 1; | 398 | lower.result_insts_len += 1; |
| 384 | _ = lower.reloc(.{ .linker_reloc = sym }); | 399 | _ = lower.reloc(.{ .linker_reloc = sym_index }, 0); |
| 385 | emit_mnemonic = .lea; | 400 | emit_mnemonic = .lea; |
| 386 | break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ | 401 | break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ |
| 387 | .base = .{ .reg = .rax }, | 402 | .base = .{ .reg = .rax }, |
| ... | @@ -390,7 +405,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) | ... | @@ -390,7 +405,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 390 | } | 405 | } |
| 391 | } | 406 | } |
| 392 | 407 | ||
| 393 | _ = lower.reloc(.{ .linker_reloc = sym }); | 408 | _ = lower.reloc(.{ .linker_reloc = sym_index }, 0); |
| 394 | if (lower.pic) switch (mnemonic) { | 409 | if (lower.pic) switch (mnemonic) { |
| 395 | .lea => { | 410 | .lea => { |
| 396 | if (elf_sym.flags.is_extern_ptr) emit_mnemonic = .mov; | 411 | if (elf_sym.flags.is_extern_ptr) emit_mnemonic = .mov; |
| ... | @@ -427,10 +442,10 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) | ... | @@ -427,10 +442,10 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 427 | } | 442 | } |
| 428 | } else if (lower.bin_file.cast(.macho)) |macho_file| { | 443 | } else if (lower.bin_file.cast(.macho)) |macho_file| { |
| 429 | const zo = macho_file.getZigObject().?; | 444 | const zo = macho_file.getZigObject().?; |
| 430 | const macho_sym = zo.symbols.items[sym.sym_index]; | 445 | const macho_sym = zo.symbols.items[sym_index]; |
| 431 | 446 | ||
| 432 | if (macho_sym.flags.tlv) { | 447 | if (macho_sym.flags.tlv) { |
| 433 | _ = lower.reloc(.{ .linker_reloc = sym }); | 448 | _ = lower.reloc(.{ .linker_reloc = sym_index }, 0); |
| 434 | lower.result_insts[lower.result_insts_len] = | 449 | lower.result_insts[lower.result_insts_len] = |
| 435 | try Instruction.new(.none, .mov, &[_]Operand{ | 450 | try Instruction.new(.none, .mov, &[_]Operand{ |
| 436 | .{ .reg = .rdi }, | 451 | .{ .reg = .rdi }, |
| ... | @@ -446,7 +461,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) | ... | @@ -446,7 +461,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 446 | break :op .{ .reg = .rax }; | 461 | break :op .{ .reg = .rax }; |
| 447 | } | 462 | } |
| 448 | 463 | ||
| 449 | _ = lower.reloc(.{ .linker_reloc = sym }); | 464 | _ = lower.reloc(.{ .linker_reloc = sym_index }, 0); |
| 450 | break :op switch (mnemonic) { | 465 | break :op switch (mnemonic) { |
| 451 | .lea => { | 466 | .lea => { |
| 452 | if (macho_sym.flags.is_extern_ptr) emit_mnemonic = .mov; | 467 | if (macho_sym.flags.is_extern_ptr) emit_mnemonic = .mov; |
| ... | @@ -490,8 +505,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -490,8 +505,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 490 | .rrrr => inst.data.rrrr.fixes, | 505 | .rrrr => inst.data.rrrr.fixes, |
| 491 | .rrri => inst.data.rrri.fixes, | 506 | .rrri => inst.data.rrri.fixes, |
| 492 | .rri_s, .rri_u => inst.data.rri.fixes, | 507 | .rri_s, .rri_u => inst.data.rri.fixes, |
| 493 | .ri_s, .ri_u => inst.data.ri.fixes, | 508 | .ri_s, .ri_u, .ri_64 => inst.data.ri.fixes, |
| 494 | .ri64, .rm, .rmi_s, .mr => inst.data.rx.fixes, | 509 | .rm, .rmi_s, .mr => inst.data.rx.fixes, |
| 495 | .mrr, .rrm, .rmr => inst.data.rrx.fixes, | 510 | .mrr, .rrm, .rmr => inst.data.rrx.fixes, |
| 496 | .rmi, .mri => inst.data.rix.fixes, | 511 | .rmi, .mri => inst.data.rix.fixes, |
| 497 | .rrmr => inst.data.rrrx.fixes, | 512 | .rrmr => inst.data.rrrx.fixes, |
| ... | @@ -525,7 +540,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -525,7 +540,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 525 | }, switch (inst.ops) { | 540 | }, switch (inst.ops) { |
| 526 | .none => &.{}, | 541 | .none => &.{}, |
| 527 | .inst => &.{ | 542 | .inst => &.{ |
| 528 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }) }, | 543 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, |
| 529 | }, | 544 | }, |
| 530 | .i_s, .i_u => &.{ | 545 | .i_s, .i_u => &.{ |
| 531 | .{ .imm = lower.imm(inst.ops, inst.data.i.i) }, | 546 | .{ .imm = lower.imm(inst.ops, inst.data.i.i) }, |
| ... | @@ -554,14 +569,10 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -554,14 +569,10 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 554 | .{ .reg = inst.data.rrri.r3 }, | 569 | .{ .reg = inst.data.rrri.r3 }, |
| 555 | .{ .imm = lower.imm(inst.ops, inst.data.rrri.i) }, | 570 | .{ .imm = lower.imm(inst.ops, inst.data.rrri.i) }, |
| 556 | }, | 571 | }, |
| 557 | .ri_s, .ri_u => &.{ | 572 | .ri_s, .ri_u, .ri_64 => &.{ |
| 558 | .{ .reg = inst.data.ri.r1 }, | 573 | .{ .reg = inst.data.ri.r1 }, |
| 559 | .{ .imm = lower.imm(inst.ops, inst.data.ri.i) }, | 574 | .{ .imm = lower.imm(inst.ops, inst.data.ri.i) }, |
| 560 | }, | 575 | }, |
| 561 | .ri64 => &.{ | ||
| 562 | .{ .reg = inst.data.rx.r1 }, | ||
| 563 | .{ .imm = lower.imm(inst.ops, inst.data.rx.payload) }, | ||
| 564 | }, | ||
| 565 | .rri_s, .rri_u => &.{ | 576 | .rri_s, .rri_u => &.{ |
| 566 | .{ .reg = inst.data.rri.r1 }, | 577 | .{ .reg = inst.data.rri.r1 }, |
| 567 | .{ .reg = inst.data.rri.r2 }, | 578 | .{ .reg = inst.data.rri.r2 }, |
| ... | @@ -631,17 +642,17 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -631,17 +642,17 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 631 | .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) }, | 642 | .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) }, |
| 632 | }, | 643 | }, |
| 633 | .extern_fn_reloc, .rel => &.{ | 644 | .extern_fn_reloc, .rel => &.{ |
| 634 | .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) }, | 645 | .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc.sym_index }, inst.data.reloc.off) }, |
| 635 | }, | 646 | }, |
| 636 | .got_reloc, .direct_reloc, .import_reloc => ops: { | 647 | .got_reloc, .direct_reloc, .import_reloc => ops: { |
| 637 | const reg = inst.data.rx.r1; | 648 | const reg = inst.data.rx.r1; |
| 638 | const extra = lower.mir.extraData(bits.Symbol, inst.data.rx.payload).data; | 649 | const extra = lower.mir.extraData(bits.SymbolOffset, inst.data.rx.payload).data; |
| 639 | _ = lower.reloc(switch (inst.ops) { | 650 | _ = lower.reloc(switch (inst.ops) { |
| 640 | .got_reloc => .{ .linker_got = extra }, | 651 | .got_reloc => .{ .linker_got = extra.sym_index }, |
| 641 | .direct_reloc => .{ .linker_direct = extra }, | 652 | .direct_reloc => .{ .linker_direct = extra.sym_index }, |
| 642 | .import_reloc => .{ .linker_import = extra }, | 653 | .import_reloc => .{ .linker_import = extra.sym_index }, |
| 643 | else => unreachable, | 654 | else => unreachable, |
| 644 | }); | 655 | }, extra.off); |
| 645 | break :ops &.{ | 656 | break :ops &.{ |
| 646 | .{ .reg = reg }, | 657 | .{ .reg = reg }, |
| 647 | .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, | 658 | .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, |
| ... | @@ -670,9 +681,6 @@ const encoder = @import("encoder.zig"); | ... | @@ -670,9 +681,6 @@ const encoder = @import("encoder.zig"); |
| 670 | const link = @import("../../link.zig"); | 681 | const link = @import("../../link.zig"); |
| 671 | const std = @import("std"); | 682 | const std = @import("std"); |
| 672 | 683 | ||
| 673 | const Air = @import("../../Air.zig"); | ||
| 674 | const Allocator = std.mem.Allocator; | ||
| 675 | const ErrorMsg = Zcu.ErrorMsg; | ||
| 676 | const Immediate = Instruction.Immediate; | 684 | const Immediate = Instruction.Immediate; |
| 677 | const Instruction = encoder.Instruction; | 685 | const Instruction = encoder.Instruction; |
| 678 | const Lower = @This(); | 686 | const Lower = @This(); |
src/arch/x86_64/Mir.zig+74-20| ... | @@ -760,8 +760,8 @@ pub const Inst = struct { | ... | @@ -760,8 +760,8 @@ pub const Inst = struct { |
| 760 | /// Uses `ri` payload. | 760 | /// Uses `ri` payload. |
| 761 | ri_u, | 761 | ri_u, |
| 762 | /// Register, 64-bit unsigned immediate operands. | 762 | /// Register, 64-bit unsigned immediate operands. |
| 763 | /// Uses `rx` payload with payload type `Imm64`. | 763 | /// Uses `ri` payload with `i` index of extra data of type `Imm64`. |
| 764 | ri64, | 764 | ri_64, |
| 765 | /// Immediate (sign-extended) operand. | 765 | /// Immediate (sign-extended) operand. |
| 766 | /// Uses `imm` payload. | 766 | /// Uses `imm` payload. |
| 767 | i_s, | 767 | i_s, |
| ... | @@ -796,7 +796,7 @@ pub const Inst = struct { | ... | @@ -796,7 +796,7 @@ pub const Inst = struct { |
| 796 | /// Uses `rrix` payload with extra data of type `Memory`. | 796 | /// Uses `rrix` payload with extra data of type `Memory`. |
| 797 | rrmi, | 797 | rrmi, |
| 798 | /// Single memory operand. | 798 | /// Single memory operand. |
| 799 | /// Uses `x` with extra data of type `Memory`. | 799 | /// Uses `x` payload with extra data of type `Memory`. |
| 800 | m, | 800 | m, |
| 801 | /// Memory, immediate (sign-extend) operands. | 801 | /// Memory, immediate (sign-extend) operands. |
| 802 | /// Uses `x` payload with extra data of type `Imm32` followed by `Memory`. | 802 | /// Uses `x` payload with extra data of type `Imm32` followed by `Memory`. |
| ... | @@ -820,16 +820,16 @@ pub const Inst = struct { | ... | @@ -820,16 +820,16 @@ pub const Inst = struct { |
| 820 | /// Uses `reloc` payload. | 820 | /// Uses `reloc` payload. |
| 821 | extern_fn_reloc, | 821 | extern_fn_reloc, |
| 822 | /// Linker relocation - GOT indirection. | 822 | /// Linker relocation - GOT indirection. |
| 823 | /// Uses `rx` payload with extra data of type `bits.Symbol`. | 823 | /// Uses `rx` payload with extra data of type `bits.SymbolOffset`. |
| 824 | got_reloc, | 824 | got_reloc, |
| 825 | /// Linker relocation - direct reference. | 825 | /// Linker relocation - direct reference. |
| 826 | /// Uses `rx` payload with extra data of type `bits.Symbol`. | 826 | /// Uses `rx` payload with extra data of type `bits.SymbolOffset`. |
| 827 | direct_reloc, | 827 | direct_reloc, |
| 828 | /// Linker relocation - imports table indirection (binding). | 828 | /// Linker relocation - imports table indirection (binding). |
| 829 | /// Uses `rx` payload with extra data of type `bits.Symbol`. | 829 | /// Uses `rx` payload with extra data of type `bits.SymbolOffset`. |
| 830 | import_reloc, | 830 | import_reloc, |
| 831 | /// Linker relocation - threadlocal variable via GOT indirection. | 831 | /// Linker relocation - threadlocal variable via GOT indirection. |
| 832 | /// Uses `rx` payload with extra data of type `bits.Symbol`. | 832 | /// Uses `rx` payload with extra data of type `bits.SymbolOffset`. |
| 833 | tlv_reloc, | 833 | tlv_reloc, |
| 834 | 834 | ||
| 835 | // Pseudo instructions: | 835 | // Pseudo instructions: |
| ... | @@ -868,16 +868,16 @@ pub const Inst = struct { | ... | @@ -868,16 +868,16 @@ pub const Inst = struct { |
| 868 | pseudo_j_nz_or_p_inst, | 868 | pseudo_j_nz_or_p_inst, |
| 869 | 869 | ||
| 870 | /// Probe alignment | 870 | /// Probe alignment |
| 871 | /// Uses `ri` payload | 871 | /// Uses `ri` payload. |
| 872 | pseudo_probe_align_ri_s, | 872 | pseudo_probe_align_ri_s, |
| 873 | /// Probe adjust unrolled | 873 | /// Probe adjust unrolled |
| 874 | /// Uses `ri` payload | 874 | /// Uses `ri` payload. |
| 875 | pseudo_probe_adjust_unrolled_ri_s, | 875 | pseudo_probe_adjust_unrolled_ri_s, |
| 876 | /// Probe adjust setup | 876 | /// Probe adjust setup |
| 877 | /// Uses `rri` payload | 877 | /// Uses `rri` payload. |
| 878 | pseudo_probe_adjust_setup_rri_s, | 878 | pseudo_probe_adjust_setup_rri_s, |
| 879 | /// Probe adjust loop | 879 | /// Probe adjust loop |
| 880 | /// Uses `rr` payload | 880 | /// Uses `rr` payload. |
| 881 | pseudo_probe_adjust_loop_rr, | 881 | pseudo_probe_adjust_loop_rr, |
| 882 | /// Push registers | 882 | /// Push registers |
| 883 | /// Uses `reg_list` payload. | 883 | /// Uses `reg_list` payload. |
| ... | @@ -893,8 +893,37 @@ pub const Inst = struct { | ... | @@ -893,8 +893,37 @@ pub const Inst = struct { |
| 893 | pseudo_dbg_line_line_column, | 893 | pseudo_dbg_line_line_column, |
| 894 | /// Start of epilogue | 894 | /// Start of epilogue |
| 895 | pseudo_dbg_epilogue_begin_none, | 895 | pseudo_dbg_epilogue_begin_none, |
| 896 | /// Start or end of inline function | 896 | /// Start of inline function |
| 897 | pseudo_dbg_inline_func, | 897 | pseudo_dbg_enter_inline_func, |
| 898 | /// End of inline function | ||
| 899 | pseudo_dbg_leave_inline_func, | ||
| 900 | /// Local argument or variable. | ||
| 901 | /// Uses `a` payload. | ||
| 902 | pseudo_dbg_local_a, | ||
| 903 | /// Local argument or variable. | ||
| 904 | /// Uses `ai` payload. | ||
| 905 | pseudo_dbg_local_ai_s, | ||
| 906 | /// Local argument or variable. | ||
| 907 | /// Uses `ai` payload. | ||
| 908 | pseudo_dbg_local_ai_u, | ||
| 909 | /// Local argument or variable. | ||
| 910 | /// Uses `ai` payload with extra data of type `Imm64`. | ||
| 911 | pseudo_dbg_local_ai_64, | ||
| 912 | /// Local argument or variable. | ||
| 913 | /// Uses `as` payload. | ||
| 914 | pseudo_dbg_local_as, | ||
| 915 | /// Local argument or variable. | ||
| 916 | /// Uses `ax` payload with extra data of type `bits.SymbolOffset`. | ||
| 917 | pseudo_dbg_local_aso, | ||
| 918 | /// Local argument or variable. | ||
| 919 | /// Uses `rx` payload with extra data of type `AirOffset`. | ||
| 920 | pseudo_dbg_local_aro, | ||
| 921 | /// Local argument or variable. | ||
| 922 | /// Uses `ax` payload with extra data of type `bits.FrameAddr`. | ||
| 923 | pseudo_dbg_local_af, | ||
| 924 | /// Local argument or variable. | ||
| 925 | /// Uses `ax` payload with extra data of type `Memory`. | ||
| 926 | pseudo_dbg_local_am, | ||
| 898 | 927 | ||
| 899 | /// Tombstone | 928 | /// Tombstone |
| 900 | /// Emitter should skip this instruction. | 929 | /// Emitter should skip this instruction. |
| ... | @@ -997,10 +1026,28 @@ pub const Inst = struct { | ... | @@ -997,10 +1026,28 @@ pub const Inst = struct { |
| 997 | fixes: Fixes = ._, | 1026 | fixes: Fixes = ._, |
| 998 | payload: u32, | 1027 | payload: u32, |
| 999 | }, | 1028 | }, |
| 1029 | ix: struct { | ||
| 1030 | payload: u32, | ||
| 1031 | }, | ||
| 1032 | a: struct { | ||
| 1033 | air_inst: Air.Inst.Index, | ||
| 1034 | }, | ||
| 1035 | ai: struct { | ||
| 1036 | air_inst: Air.Inst.Index, | ||
| 1037 | i: u32, | ||
| 1038 | }, | ||
| 1039 | as: struct { | ||
| 1040 | air_inst: Air.Inst.Index, | ||
| 1041 | sym_index: u32, | ||
| 1042 | }, | ||
| 1043 | ax: struct { | ||
| 1044 | air_inst: Air.Inst.Index, | ||
| 1045 | payload: u32, | ||
| 1046 | }, | ||
| 1000 | /// Relocation for the linker where: | 1047 | /// Relocation for the linker where: |
| 1001 | /// * `atom_index` is the index of the source | ||
| 1002 | /// * `sym_index` is the index of the target | 1048 | /// * `sym_index` is the index of the target |
| 1003 | reloc: bits.Symbol, | 1049 | /// * `off` is the offset from the target |
| 1050 | reloc: bits.SymbolOffset, | ||
| 1004 | /// Debug line and column position | 1051 | /// Debug line and column position |
| 1005 | line_column: struct { | 1052 | line_column: struct { |
| 1006 | line: u32, | 1053 | line: u32, |
| ... | @@ -1020,6 +1067,8 @@ pub const Inst = struct { | ... | @@ -1020,6 +1067,8 @@ pub const Inst = struct { |
| 1020 | } | 1067 | } |
| 1021 | }; | 1068 | }; |
| 1022 | 1069 | ||
| 1070 | pub const AirOffset = struct { air_inst: Air.Inst.Index, off: i32 }; | ||
| 1071 | |||
| 1023 | /// Used in conjunction with payload to transfer a list of used registers in a compact manner. | 1072 | /// Used in conjunction with payload to transfer a list of used registers in a compact manner. |
| 1024 | pub const RegisterList = struct { | 1073 | pub const RegisterList = struct { |
| 1025 | bitset: BitSet = BitSet.initEmpty(), | 1074 | bitset: BitSet = BitSet.initEmpty(), |
| ... | @@ -1118,15 +1167,13 @@ pub const Memory = struct { | ... | @@ -1118,15 +1167,13 @@ pub const Memory = struct { |
| 1118 | .none => undefined, | 1167 | .none => undefined, |
| 1119 | .reg => |reg| @intFromEnum(reg), | 1168 | .reg => |reg| @intFromEnum(reg), |
| 1120 | .frame => |frame_index| @intFromEnum(frame_index), | 1169 | .frame => |frame_index| @intFromEnum(frame_index), |
| 1121 | .reloc => |symbol| symbol.sym_index, | 1170 | .reloc => |sym_index| sym_index, |
| 1122 | }, | 1171 | }, |
| 1123 | .off = switch (mem.mod) { | 1172 | .off = switch (mem.mod) { |
| 1124 | .rm => |rm| @bitCast(rm.disp), | 1173 | .rm => |rm| @bitCast(rm.disp), |
| 1125 | .off => |off| @truncate(off), | 1174 | .off => |off| @truncate(off), |
| 1126 | }, | 1175 | }, |
| 1127 | .extra = if (mem.base == .reloc) | 1176 | .extra = if (mem.mod == .off) |
| 1128 | mem.base.reloc.atom_index | ||
| 1129 | else if (mem.mod == .off) | ||
| 1130 | @intCast(mem.mod.off >> 32) | 1177 | @intCast(mem.mod.off >> 32) |
| 1131 | else | 1178 | else |
| 1132 | undefined, | 1179 | undefined, |
| ... | @@ -1146,7 +1193,7 @@ pub const Memory = struct { | ... | @@ -1146,7 +1193,7 @@ pub const Memory = struct { |
| 1146 | .none => .none, | 1193 | .none => .none, |
| 1147 | .reg => .{ .reg = @enumFromInt(mem.base) }, | 1194 | .reg => .{ .reg = @enumFromInt(mem.base) }, |
| 1148 | .frame => .{ .frame = @enumFromInt(mem.base) }, | 1195 | .frame => .{ .frame = @enumFromInt(mem.base) }, |
| 1149 | .reloc => .{ .reloc = .{ .atom_index = mem.extra, .sym_index = mem.base } }, | 1196 | .reloc => .{ .reloc = mem.base }, |
| 1150 | }, | 1197 | }, |
| 1151 | .scale_index = switch (mem.info.index) { | 1198 | .scale_index = switch (mem.info.index) { |
| 1152 | .none => null, | 1199 | .none => null, |
| ... | @@ -1186,6 +1233,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: | ... | @@ -1186,6 +1233,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: |
| 1186 | @field(result, field.name) = switch (field.type) { | 1233 | @field(result, field.name) = switch (field.type) { |
| 1187 | u32 => mir.extra[i], | 1234 | u32 => mir.extra[i], |
| 1188 | i32, Memory.Info => @bitCast(mir.extra[i]), | 1235 | i32, Memory.Info => @bitCast(mir.extra[i]), |
| 1236 | bits.FrameIndex, Air.Inst.Index => @enumFromInt(mir.extra[i]), | ||
| 1189 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), | 1237 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), |
| 1190 | }; | 1238 | }; |
| 1191 | i += 1; | 1239 | i += 1; |
| ... | @@ -1201,6 +1249,11 @@ pub const FrameLoc = struct { | ... | @@ -1201,6 +1249,11 @@ pub const FrameLoc = struct { |
| 1201 | disp: i32, | 1249 | disp: i32, |
| 1202 | }; | 1250 | }; |
| 1203 | 1251 | ||
| 1252 | pub fn resolveFrameAddr(mir: Mir, frame_addr: bits.FrameAddr) bits.RegisterOffset { | ||
| 1253 | const frame_loc = mir.frame_locs.get(@intFromEnum(frame_addr.index)); | ||
| 1254 | return .{ .reg = frame_loc.base, .off = frame_loc.disp + frame_addr.off }; | ||
| 1255 | } | ||
| 1256 | |||
| 1204 | pub fn resolveFrameLoc(mir: Mir, mem: Memory) Memory { | 1257 | pub fn resolveFrameLoc(mir: Mir, mem: Memory) Memory { |
| 1205 | return switch (mem.info.base) { | 1258 | return switch (mem.info.base) { |
| 1206 | .none, .reg, .reloc => mem, | 1259 | .none, .reg, .reloc => mem, |
| ... | @@ -1225,6 +1278,7 @@ const builtin = @import("builtin"); | ... | @@ -1225,6 +1278,7 @@ const builtin = @import("builtin"); |
| 1225 | const encoder = @import("encoder.zig"); | 1278 | const encoder = @import("encoder.zig"); |
| 1226 | const std = @import("std"); | 1279 | const std = @import("std"); |
| 1227 | 1280 | ||
| 1281 | const Air = @import("../../Air.zig"); | ||
| 1228 | const IntegerBitSet = std.bit_set.IntegerBitSet; | 1282 | const IntegerBitSet = std.bit_set.IntegerBitSet; |
| 1229 | const InternPool = @import("../../InternPool.zig"); | 1283 | const InternPool = @import("../../InternPool.zig"); |
| 1230 | const Mir = @This(); | 1284 | const Mir = @This(); |
src/arch/x86_64/bits.zig+12-27| ... | @@ -447,26 +447,11 @@ pub const FrameIndex = enum(u32) { | ... | @@ -447,26 +447,11 @@ pub const FrameIndex = enum(u32) { |
| 447 | } | 447 | } |
| 448 | }; | 448 | }; |
| 449 | 449 | ||
| 450 | /// A linker symbol not yet allocated in VM. | 450 | pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; |
| 451 | pub const Symbol = struct { | ||
| 452 | /// Index of the containing atom. | ||
| 453 | atom_index: u32, | ||
| 454 | /// Index into the linker's symbol table. | ||
| 455 | sym_index: u32, | ||
| 456 | 451 | ||
| 457 | pub fn format( | 452 | pub const RegisterOffset = struct { reg: Register, off: i32 = 0 }; |
| 458 | sym: Symbol, | 453 | |
| 459 | comptime fmt: []const u8, | 454 | pub const SymbolOffset = struct { sym_index: u32, off: i32 = 0 }; |
| 460 | options: std.fmt.FormatOptions, | ||
| 461 | writer: anytype, | ||
| 462 | ) @TypeOf(writer).Error!void { | ||
| 463 | try writer.writeAll("Symbol("); | ||
| 464 | try std.fmt.formatType(sym.atom_index, fmt, options, writer, 0); | ||
| 465 | try writer.writeAll(", "); | ||
| 466 | try std.fmt.formatType(sym.sym_index, fmt, options, writer, 0); | ||
| 467 | try writer.writeByte(')'); | ||
| 468 | } | ||
| 469 | }; | ||
| 470 | 455 | ||
| 471 | pub const Memory = struct { | 456 | pub const Memory = struct { |
| 472 | base: Base, | 457 | base: Base, |
| ... | @@ -476,7 +461,7 @@ pub const Memory = struct { | ... | @@ -476,7 +461,7 @@ pub const Memory = struct { |
| 476 | none, | 461 | none, |
| 477 | reg: Register, | 462 | reg: Register, |
| 478 | frame: FrameIndex, | 463 | frame: FrameIndex, |
| 479 | reloc: Symbol, | 464 | reloc: u32, |
| 480 | 465 | ||
| 481 | pub const Tag = @typeInfo(Base).Union.tag_type.?; | 466 | pub const Tag = @typeInfo(Base).Union.tag_type.?; |
| 482 | 467 | ||
| ... | @@ -568,7 +553,7 @@ pub const Memory = struct { | ... | @@ -568,7 +553,7 @@ pub const Memory = struct { |
| 568 | pub const Immediate = union(enum) { | 553 | pub const Immediate = union(enum) { |
| 569 | signed: i32, | 554 | signed: i32, |
| 570 | unsigned: u64, | 555 | unsigned: u64, |
| 571 | reloc: Symbol, | 556 | reloc: SymbolOffset, |
| 572 | 557 | ||
| 573 | pub fn u(x: u64) Immediate { | 558 | pub fn u(x: u64) Immediate { |
| 574 | return .{ .unsigned = x }; | 559 | return .{ .unsigned = x }; |
| ... | @@ -578,19 +563,19 @@ pub const Immediate = union(enum) { | ... | @@ -578,19 +563,19 @@ pub const Immediate = union(enum) { |
| 578 | return .{ .signed = x }; | 563 | return .{ .signed = x }; |
| 579 | } | 564 | } |
| 580 | 565 | ||
| 581 | pub fn rel(symbol: Symbol) Immediate { | 566 | pub fn rel(sym_off: SymbolOffset) Immediate { |
| 582 | return .{ .reloc = symbol }; | 567 | return .{ .reloc = sym_off }; |
| 583 | } | 568 | } |
| 584 | 569 | ||
| 585 | pub fn format( | 570 | pub fn format( |
| 586 | imm: Immediate, | 571 | imm: Immediate, |
| 587 | comptime fmt: []const u8, | 572 | comptime _: []const u8, |
| 588 | options: std.fmt.FormatOptions, | 573 | _: std.fmt.FormatOptions, |
| 589 | writer: anytype, | 574 | writer: anytype, |
| 590 | ) @TypeOf(writer).Error!void { | 575 | ) @TypeOf(writer).Error!void { |
| 591 | switch (imm) { | 576 | switch (imm) { |
| 592 | .reloc => |x| try std.fmt.formatType(x, fmt, options, writer, 0), | 577 | inline else => |int| try writer.print("{d}", .{int}), |
| 593 | inline else => |x| try writer.print("{d}", .{x}), | 578 | .reloc => |sym_off| try writer.print("Symbol({[sym_index]d}) + {[off]d}", sym_off), |
| 594 | } | 579 | } |
| 595 | } | 580 | } |
| 596 | }; | 581 | }; |
src/arch/x86_64/encoder.zig+15-12| ... | @@ -128,8 +128,8 @@ pub const Instruction = struct { | ... | @@ -128,8 +128,8 @@ pub const Instruction = struct { |
| 128 | } }; | 128 | } }; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | pub fn rip(ptr_size: PtrSize, disp: i32) Memory { | 131 | pub fn rip(ptr_size: PtrSize, displacement: i32) Memory { |
| 132 | return .{ .rip = .{ .ptr_size = ptr_size, .disp = disp } }; | 132 | return .{ .rip = .{ .ptr_size = ptr_size, .disp = displacement } }; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | pub fn isSegmentRegister(mem: Memory) bool { | 135 | pub fn isSegmentRegister(mem: Memory) bool { |
| ... | @@ -158,6 +158,14 @@ pub const Instruction = struct { | ... | @@ -158,6 +158,14 @@ pub const Instruction = struct { |
| 158 | }; | 158 | }; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | pub fn disp(mem: Memory) Immediate { | ||
| 162 | return switch (mem) { | ||
| 163 | .sib => |s| Immediate.s(s.disp), | ||
| 164 | .rip => |r| Immediate.s(r.disp), | ||
| 165 | .moffs => |m| Immediate.u(m.offset), | ||
| 166 | }; | ||
| 167 | } | ||
| 168 | |||
| 161 | pub fn bitSize(mem: Memory) u64 { | 169 | pub fn bitSize(mem: Memory) u64 { |
| 162 | return switch (mem) { | 170 | return switch (mem) { |
| 163 | .rip => |r| r.ptr_size.bitSize(), | 171 | .rip => |r| r.ptr_size.bitSize(), |
| ... | @@ -258,17 +266,12 @@ pub const Instruction = struct { | ... | @@ -258,17 +266,12 @@ pub const Instruction = struct { |
| 258 | 266 | ||
| 259 | try writer.writeByte('['); | 267 | try writer.writeByte('['); |
| 260 | 268 | ||
| 261 | var any = false; | 269 | var any = true; |
| 262 | switch (sib.base) { | 270 | switch (sib.base) { |
| 263 | .none => {}, | 271 | .none => any = false, |
| 264 | .reg => |reg| { | 272 | .reg => |reg| try writer.print("{s}", .{@tagName(reg)}), |
| 265 | try writer.print("{s}", .{@tagName(reg)}); | 273 | .frame => |frame_index| try writer.print("{}", .{frame_index}), |
| 266 | any = true; | 274 | .reloc => |sym_index| try writer.print("Symbol({d})", .{sym_index}), |
| 267 | }, | ||
| 268 | inline .frame, .reloc => |payload| { | ||
| 269 | try writer.print("{}", .{payload}); | ||
| 270 | any = true; | ||
| 271 | }, | ||
| 272 | } | 275 | } |
| 273 | if (mem.scaleIndex()) |si| { | 276 | if (mem.scaleIndex()) |si| { |
| 274 | if (any) try writer.writeAll(" + "); | 277 | if (any) try writer.writeAll(" + "); |
src/codegen/c.zig+4-3| ... | @@ -3293,7 +3293,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, | ... | @@ -3293,7 +3293,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3293 | 3293 | ||
| 3294 | .dbg_stmt => try airDbgStmt(f, inst), | 3294 | .dbg_stmt => try airDbgStmt(f, inst), |
| 3295 | .dbg_inline_block => try airDbgInlineBlock(f, inst), | 3295 | .dbg_inline_block => try airDbgInlineBlock(f, inst), |
| 3296 | .dbg_var_ptr, .dbg_var_val => try airDbgVar(f, inst), | 3296 | .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => try airDbgVar(f, inst), |
| 3297 | 3297 | ||
| 3298 | .call => try airCall(f, inst, .auto), | 3298 | .call => try airCall(f, inst, .auto), |
| 3299 | .call_always_tail => .none, | 3299 | .call_always_tail => .none, |
| ... | @@ -4590,14 +4590,15 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4590,14 +4590,15 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4590 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { | 4590 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4591 | const pt = f.object.dg.pt; | 4591 | const pt = f.object.dg.pt; |
| 4592 | const zcu = pt.zcu; | 4592 | const zcu = pt.zcu; |
| 4593 | const tag = f.air.instructions.items(.tag)[@intFromEnum(inst)]; | ||
| 4593 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 4594 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 4594 | const name = f.air.nullTerminatedString(pl_op.payload); | 4595 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 4595 | const operand_is_undef = if (try f.air.value(pl_op.operand, pt)) |v| v.isUndefDeep(zcu) else false; | 4596 | const operand_is_undef = if (try f.air.value(pl_op.operand, pt)) |v| v.isUndefDeep(zcu) else false; |
| 4596 | if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand); | 4597 | if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand); |
| 4597 | 4598 | ||
| 4598 | try reap(f, inst, &.{pl_op.operand}); | 4599 | try reap(f, inst, &.{pl_op.operand}); |
| 4599 | const writer = f.object.writer(); | 4600 | const writer = f.object.writer(); |
| 4600 | try writer.print("/* var:{s} */\n", .{name}); | 4601 | try writer.print("/* {s}:{s} */\n", .{ @tagName(tag), name.toSlice(f.air) }); |
| 4601 | return .none; | 4602 | return .none; |
| 4602 | } | 4603 | } |
| 4603 | 4604 |
src/codegen/llvm.zig+24-10| ... | @@ -1665,6 +1665,7 @@ pub const Object = struct { | ... | @@ -1665,6 +1665,7 @@ pub const Object = struct { |
| 1665 | .ret_ptr = ret_ptr, | 1665 | .ret_ptr = ret_ptr, |
| 1666 | .args = args.items, | 1666 | .args = args.items, |
| 1667 | .arg_index = 0, | 1667 | .arg_index = 0, |
| 1668 | .arg_inline_index = 0, | ||
| 1668 | .func_inst_table = .{}, | 1669 | .func_inst_table = .{}, |
| 1669 | .blocks = .{}, | 1670 | .blocks = .{}, |
| 1670 | .sync_scope = if (owner_mod.single_threaded) .singlethread else .system, | 1671 | .sync_scope = if (owner_mod.single_threaded) .singlethread else .system, |
| ... | @@ -4769,7 +4770,8 @@ pub const FuncGen = struct { | ... | @@ -4769,7 +4770,8 @@ pub const FuncGen = struct { |
| 4769 | /// it omits 0-bit types. If the function uses sret as the first parameter, | 4770 | /// it omits 0-bit types. If the function uses sret as the first parameter, |
| 4770 | /// this slice does not include it. | 4771 | /// this slice does not include it. |
| 4771 | args: []const Builder.Value, | 4772 | args: []const Builder.Value, |
| 4772 | arg_index: usize, | 4773 | arg_index: u32, |
| 4774 | arg_inline_index: u32, | ||
| 4773 | 4775 | ||
| 4774 | err_ret_trace: Builder.Value = .none, | 4776 | err_ret_trace: Builder.Value = .none, |
| 4775 | 4777 | ||
| ... | @@ -5082,7 +5084,8 @@ pub const FuncGen = struct { | ... | @@ -5082,7 +5084,8 @@ pub const FuncGen = struct { |
| 5082 | .dbg_stmt => try self.airDbgStmt(inst), | 5084 | .dbg_stmt => try self.airDbgStmt(inst), |
| 5083 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | 5085 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 5084 | .dbg_var_ptr => try self.airDbgVarPtr(inst), | 5086 | .dbg_var_ptr => try self.airDbgVarPtr(inst), |
| 5085 | .dbg_var_val => try self.airDbgVarVal(inst), | 5087 | .dbg_var_val => try self.airDbgVarVal(inst, false), |
| 5088 | .dbg_arg_inline => try self.airDbgVarVal(inst, true), | ||
| 5086 | 5089 | ||
| 5087 | .c_va_arg => try self.airCVaArg(inst), | 5090 | .c_va_arg => try self.airCVaArg(inst), |
| 5088 | .c_va_copy => try self.airCVaCopy(inst), | 5091 | .c_va_copy => try self.airCVaCopy(inst), |
| ... | @@ -6677,6 +6680,7 @@ pub const FuncGen = struct { | ... | @@ -6677,6 +6680,7 @@ pub const FuncGen = struct { |
| 6677 | fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6680 | fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6678 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6681 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6679 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | 6682 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 6683 | self.arg_inline_index = 0; | ||
| 6680 | return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | 6684 | return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); |
| 6681 | } | 6685 | } |
| 6682 | 6686 | ||
| ... | @@ -6685,11 +6689,11 @@ pub const FuncGen = struct { | ... | @@ -6685,11 +6689,11 @@ pub const FuncGen = struct { |
| 6685 | const mod = o.pt.zcu; | 6689 | const mod = o.pt.zcu; |
| 6686 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6690 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6687 | const operand = try self.resolveInst(pl_op.operand); | 6691 | const operand = try self.resolveInst(pl_op.operand); |
| 6688 | const name = self.air.nullTerminatedString(pl_op.payload); | 6692 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 6689 | const ptr_ty = self.typeOf(pl_op.operand); | 6693 | const ptr_ty = self.typeOf(pl_op.operand); |
| 6690 | 6694 | ||
| 6691 | const debug_local_var = try o.builder.debugLocalVar( | 6695 | const debug_local_var = try o.builder.debugLocalVar( |
| 6692 | try o.builder.metadataString(name), | 6696 | try o.builder.metadataString(name.toSlice(self.air)), |
| 6693 | self.file, | 6697 | self.file, |
| 6694 | self.scope, | 6698 | self.scope, |
| 6695 | self.prev_dbg_line, | 6699 | self.prev_dbg_line, |
| ... | @@ -6712,15 +6716,25 @@ pub const FuncGen = struct { | ... | @@ -6712,15 +6716,25 @@ pub const FuncGen = struct { |
| 6712 | return .none; | 6716 | return .none; |
| 6713 | } | 6717 | } |
| 6714 | 6718 | ||
| 6715 | fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6719 | fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Value { |
| 6716 | const o = self.ng.object; | 6720 | const o = self.ng.object; |
| 6717 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6721 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6718 | const operand = try self.resolveInst(pl_op.operand); | 6722 | const operand = try self.resolveInst(pl_op.operand); |
| 6719 | const operand_ty = self.typeOf(pl_op.operand); | 6723 | const operand_ty = self.typeOf(pl_op.operand); |
| 6720 | const name = self.air.nullTerminatedString(pl_op.payload); | 6724 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 6721 | 6725 | ||
| 6722 | const debug_local_var = try o.builder.debugLocalVar( | 6726 | const debug_local_var = if (is_arg) try o.builder.debugParameter( |
| 6723 | try o.builder.metadataString(name), | 6727 | try o.builder.metadataString(name.toSlice(self.air)), |
| 6728 | self.file, | ||
| 6729 | self.scope, | ||
| 6730 | self.prev_dbg_line, | ||
| 6731 | try o.lowerDebugType(operand_ty), | ||
| 6732 | arg_no: { | ||
| 6733 | self.arg_inline_index += 1; | ||
| 6734 | break :arg_no self.arg_inline_index; | ||
| 6735 | }, | ||
| 6736 | ) else try o.builder.debugLocalVar( | ||
| 6737 | try o.builder.metadataString(name.toSlice(self.air)), | ||
| 6724 | self.file, | 6738 | self.file, |
| 6725 | self.scope, | 6739 | self.scope, |
| 6726 | self.prev_dbg_line, | 6740 | self.prev_dbg_line, |
| ... | @@ -8835,12 +8849,12 @@ pub const FuncGen = struct { | ... | @@ -8835,12 +8849,12 @@ pub const FuncGen = struct { |
| 8835 | const lbrace_col = func.lbrace_column + 1; | 8849 | const lbrace_col = func.lbrace_column + 1; |
| 8836 | 8850 | ||
| 8837 | const debug_parameter = try o.builder.debugParameter( | 8851 | const debug_parameter = try o.builder.debugParameter( |
| 8838 | try o.builder.metadataString(self.air.nullTerminatedString(@intFromEnum(name))), | 8852 | try o.builder.metadataString(name.toSlice(self.air)), |
| 8839 | self.file, | 8853 | self.file, |
| 8840 | self.scope, | 8854 | self.scope, |
| 8841 | lbrace_line, | 8855 | lbrace_line, |
| 8842 | try o.lowerDebugType(inst_ty), | 8856 | try o.lowerDebugType(inst_ty), |
| 8843 | @intCast(self.arg_index), | 8857 | self.arg_index, |
| 8844 | ); | 8858 | ); |
| 8845 | 8859 | ||
| 8846 | const old_location = self.wip.debug_location; | 8860 | const old_location = self.wip.debug_location; |
src/codegen/spirv.zig+2-2| ... | @@ -6366,8 +6366,8 @@ const NavGen = struct { | ... | @@ -6366,8 +6366,8 @@ const NavGen = struct { |
| 6366 | fn airDbgVar(self: *NavGen, inst: Air.Inst.Index) !void { | 6366 | fn airDbgVar(self: *NavGen, inst: Air.Inst.Index) !void { |
| 6367 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6367 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6368 | const target_id = try self.resolve(pl_op.operand); | 6368 | const target_id = try self.resolve(pl_op.operand); |
| 6369 | const name = self.air.nullTerminatedString(pl_op.payload); | 6369 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 6370 | try self.spv.debugName(target_id, name); | 6370 | try self.spv.debugName(target_id, name.toSlice(self.air)); |
| 6371 | } | 6371 | } |
| 6372 | 6372 | ||
| 6373 | fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef { | 6373 | fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
src/link/C.zig+11-1| ... | @@ -317,8 +317,18 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ! | ... | @@ -317,8 +317,18 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ! |
| 317 | defer tracy.end(); | 317 | defer tracy.end(); |
| 318 | 318 | ||
| 319 | const gpa = self.base.comp.gpa; | 319 | const gpa = self.base.comp.gpa; |
| 320 | |||
| 321 | const zcu = pt.zcu; | 320 | const zcu = pt.zcu; |
| 321 | const ip = &zcu.intern_pool; | ||
| 322 | |||
| 323 | const nav = ip.getNav(nav_index); | ||
| 324 | const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) { | ||
| 325 | .func => return, | ||
| 326 | .@"extern" => .none, | ||
| 327 | .variable => |variable| variable.init, | ||
| 328 | else => nav.status.resolved.val, | ||
| 329 | }; | ||
| 330 | if (nav_init != .none and !Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) return; | ||
| 331 | |||
| 322 | const gop = try self.navs.getOrPut(gpa, nav_index); | 332 | const gop = try self.navs.getOrPut(gpa, nav_index); |
| 323 | errdefer _ = self.navs.pop(); | 333 | errdefer _ = self.navs.pop(); |
| 324 | if (!gop.found_existing) gop.value_ptr.* = .{}; | 334 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
src/link/Coff.zig+2-1| ... | @@ -1207,6 +1207,7 @@ pub fn updateNav( | ... | @@ -1207,6 +1207,7 @@ pub fn updateNav( |
| 1207 | 1207 | ||
| 1208 | const nav_val = zcu.navValue(nav_index); | 1208 | const nav_val = zcu.navValue(nav_index); |
| 1209 | const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { | 1209 | const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { |
| 1210 | .func => return, | ||
| 1210 | .variable => |variable| Value.fromInterned(variable.init), | 1211 | .variable => |variable| Value.fromInterned(variable.init), |
| 1211 | .@"extern" => |@"extern"| { | 1212 | .@"extern" => |@"extern"| { |
| 1212 | if (ip.isFunctionType(@"extern".ty)) return; | 1213 | if (ip.isFunctionType(@"extern".ty)) return; |
| ... | @@ -1220,7 +1221,7 @@ pub fn updateNav( | ... | @@ -1220,7 +1221,7 @@ pub fn updateNav( |
| 1220 | else => nav_val, | 1221 | else => nav_val, |
| 1221 | }; | 1222 | }; |
| 1222 | 1223 | ||
| 1223 | if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) { | 1224 | if (nav_init.typeOf(zcu).hasRuntimeBits(pt)) { |
| 1224 | const atom_index = try self.getOrCreateAtomForNav(nav_index); | 1225 | const atom_index = try self.getOrCreateAtomForNav(nav_index); |
| 1225 | Atom.freeRelocations(self, atom_index); | 1226 | Atom.freeRelocations(self, atom_index); |
| 1226 | const atom = self.getAtom(atom_index); | 1227 | const atom = self.getAtom(atom_index); |
src/link/Dwarf.zig+339-150| ... | @@ -21,8 +21,9 @@ pub const UpdateError = | ... | @@ -21,8 +21,9 @@ pub const UpdateError = |
| 21 | std.fs.File.OpenError || | 21 | std.fs.File.OpenError || |
| 22 | std.fs.File.SetEndPosError || | 22 | std.fs.File.SetEndPosError || |
| 23 | std.fs.File.CopyRangeError || | 23 | std.fs.File.CopyRangeError || |
| 24 | std.fs.File.PReadError || | ||
| 24 | std.fs.File.PWriteError || | 25 | std.fs.File.PWriteError || |
| 25 | error{ Overflow, Underflow, UnexpectedEndOfFile }; | 26 | error{ EndOfStream, Overflow, Underflow, UnexpectedEndOfFile }; |
| 26 | 27 | ||
| 27 | pub const FlushError = | 28 | pub const FlushError = |
| 28 | UpdateError || | 29 | UpdateError || |
| ... | @@ -253,10 +254,8 @@ const Section = struct { | ... | @@ -253,10 +254,8 @@ const Section = struct { |
| 253 | .trailer_len = trailer_len, | 254 | .trailer_len = trailer_len, |
| 254 | .len = header_len + trailer_len, | 255 | .len = header_len + trailer_len, |
| 255 | .entries = .{}, | 256 | .entries = .{}, |
| 256 | .cross_entry_relocs = .{}, | ||
| 257 | .cross_unit_relocs = .{}, | 257 | .cross_unit_relocs = .{}, |
| 258 | .cross_section_relocs = .{}, | 258 | .cross_section_relocs = .{}, |
| 259 | .external_relocs = .{}, | ||
| 260 | }; | 259 | }; |
| 261 | if (sec.last.unwrap()) |last_unit| { | 260 | if (sec.last.unwrap()) |last_unit| { |
| 262 | const last_unit_ptr = sec.getUnit(last_unit); | 261 | const last_unit_ptr = sec.getUnit(last_unit); |
| ... | @@ -358,10 +357,8 @@ const Unit = struct { | ... | @@ -358,10 +357,8 @@ const Unit = struct { |
| 358 | /// data length in bytes | 357 | /// data length in bytes |
| 359 | len: u32, | 358 | len: u32, |
| 360 | entries: std.ArrayListUnmanaged(Entry), | 359 | entries: std.ArrayListUnmanaged(Entry), |
| 361 | cross_entry_relocs: std.ArrayListUnmanaged(CrossEntryReloc), | ||
| 362 | cross_unit_relocs: std.ArrayListUnmanaged(CrossUnitReloc), | 360 | cross_unit_relocs: std.ArrayListUnmanaged(CrossUnitReloc), |
| 363 | cross_section_relocs: std.ArrayListUnmanaged(CrossSectionReloc), | 361 | cross_section_relocs: std.ArrayListUnmanaged(CrossSectionReloc), |
| 364 | external_relocs: std.ArrayListUnmanaged(ExternalReloc), | ||
| 365 | 362 | ||
| 366 | const Index = enum(u32) { | 363 | const Index = enum(u32) { |
| 367 | main, | 364 | main, |
| ... | @@ -381,12 +378,16 @@ const Unit = struct { | ... | @@ -381,12 +378,16 @@ const Unit = struct { |
| 381 | } | 378 | } |
| 382 | }; | 379 | }; |
| 383 | 380 | ||
| 381 | fn clear(unit: *Unit) void { | ||
| 382 | unit.cross_unit_relocs.clearRetainingCapacity(); | ||
| 383 | unit.cross_section_relocs.clearRetainingCapacity(); | ||
| 384 | } | ||
| 385 | |||
| 384 | fn deinit(unit: *Unit, gpa: std.mem.Allocator) void { | 386 | fn deinit(unit: *Unit, gpa: std.mem.Allocator) void { |
| 387 | for (unit.entries.items) |*entry| entry.deinit(gpa); | ||
| 385 | unit.entries.deinit(gpa); | 388 | unit.entries.deinit(gpa); |
| 386 | unit.cross_entry_relocs.deinit(gpa); | ||
| 387 | unit.cross_unit_relocs.deinit(gpa); | 389 | unit.cross_unit_relocs.deinit(gpa); |
| 388 | unit.cross_section_relocs.deinit(gpa); | 390 | unit.cross_section_relocs.deinit(gpa); |
| 389 | unit.external_relocs.deinit(gpa); | ||
| 390 | unit.* = undefined; | 391 | unit.* = undefined; |
| 391 | } | 392 | } |
| 392 | 393 | ||
| ... | @@ -398,6 +399,10 @@ const Unit = struct { | ... | @@ -398,6 +399,10 @@ const Unit = struct { |
| 398 | .next = .none, | 399 | .next = .none, |
| 399 | .off = 0, | 400 | .off = 0, |
| 400 | .len = 0, | 401 | .len = 0, |
| 402 | .cross_entry_relocs = .{}, | ||
| 403 | .cross_unit_relocs = .{}, | ||
| 404 | .cross_section_relocs = .{}, | ||
| 405 | .external_relocs = .{}, | ||
| 401 | }; | 406 | }; |
| 402 | if (unit.last.unwrap()) |last_entry| { | 407 | if (unit.last.unwrap()) |last_entry| { |
| 403 | const last_entry_ptr = unit.getEntry(last_entry); | 408 | const last_entry_ptr = unit.getEntry(last_entry); |
| ... | @@ -451,6 +456,14 @@ const Unit = struct { | ... | @@ -451,6 +456,14 @@ const Unit = struct { |
| 451 | unit_ptr.len = len; | 456 | unit_ptr.len = len; |
| 452 | } | 457 | } |
| 453 | 458 | ||
| 459 | fn trim(unit: *Unit) void { | ||
| 460 | const len = unit.getEntry(unit.first.unwrap() orelse return).off; | ||
| 461 | if (len == 0) return; | ||
| 462 | for (unit.entries.items) |*entry| entry.off -= len; | ||
| 463 | unit.off += len; | ||
| 464 | unit.len -= len; | ||
| 465 | } | ||
| 466 | |||
| 454 | fn move(unit: *Unit, sec: *Section, dwarf: *Dwarf, new_off: u32) UpdateError!void { | 467 | fn move(unit: *Unit, sec: *Section, dwarf: *Dwarf, new_off: u32) UpdateError!void { |
| 455 | if (unit.off == new_off) return; | 468 | if (unit.off == new_off) return; |
| 456 | if (try dwarf.getFile().?.copyRangeAll( | 469 | if (try dwarf.getFile().?.copyRangeAll( |
| ... | @@ -463,6 +476,7 @@ const Unit = struct { | ... | @@ -463,6 +476,7 @@ const Unit = struct { |
| 463 | } | 476 | } |
| 464 | 477 | ||
| 465 | fn resizeHeader(unit: *Unit, sec: *Section, dwarf: *Dwarf, len: u32) UpdateError!void { | 478 | fn resizeHeader(unit: *Unit, sec: *Section, dwarf: *Dwarf, len: u32) UpdateError!void { |
| 479 | unit.trim(); | ||
| 466 | if (unit.header_len == len) return; | 480 | if (unit.header_len == len) return; |
| 467 | const available_len = if (unit.prev.unwrap()) |prev_unit| prev_excess: { | 481 | const available_len = if (unit.prev.unwrap()) |prev_unit| prev_excess: { |
| 468 | const prev_unit_ptr = sec.getUnit(prev_unit); | 482 | const prev_unit_ptr = sec.getUnit(prev_unit); |
| ... | @@ -535,23 +549,11 @@ const Unit = struct { | ... | @@ -535,23 +549,11 @@ const Unit = struct { |
| 535 | } | 549 | } |
| 536 | 550 | ||
| 537 | fn resolveRelocs(unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void { | 551 | fn resolveRelocs(unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void { |
| 538 | for (unit.cross_entry_relocs.items) |reloc| { | 552 | const unit_off = sec.off + unit.off; |
| 539 | try dwarf.resolveReloc( | ||
| 540 | sec.off + unit.off + (if (reloc.source_entry.unwrap()) |source_entry| | ||
| 541 | unit.header_len + unit.getEntry(source_entry).off | ||
| 542 | else | ||
| 543 | 0) + reloc.source_off, | ||
| 544 | unit.off + unit.header_len + unit.getEntry(reloc.target_entry).assertNonEmpty(unit, sec, dwarf).off + reloc.target_off, | ||
| 545 | dwarf.sectionOffsetBytes(), | ||
| 546 | ); | ||
| 547 | } | ||
| 548 | for (unit.cross_unit_relocs.items) |reloc| { | 553 | for (unit.cross_unit_relocs.items) |reloc| { |
| 549 | const target_unit = sec.getUnit(reloc.target_unit); | 554 | const target_unit = sec.getUnit(reloc.target_unit); |
| 550 | try dwarf.resolveReloc( | 555 | try dwarf.resolveReloc( |
| 551 | sec.off + unit.off + (if (reloc.source_entry.unwrap()) |source_entry| | 556 | unit_off + reloc.source_off, |
| 552 | unit.header_len + unit.getEntry(source_entry).off | ||
| 553 | else | ||
| 554 | 0) + reloc.source_off, | ||
| 555 | target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry| | 557 | target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry| |
| 556 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off | 558 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off |
| 557 | else | 559 | else |
| ... | @@ -565,10 +567,7 @@ const Unit = struct { | ... | @@ -565,10 +567,7 @@ const Unit = struct { |
| 565 | }; | 567 | }; |
| 566 | const target_unit = target_sec.getUnit(reloc.target_unit); | 568 | const target_unit = target_sec.getUnit(reloc.target_unit); |
| 567 | try dwarf.resolveReloc( | 569 | try dwarf.resolveReloc( |
| 568 | sec.off + unit.off + (if (reloc.source_entry.unwrap()) |source_entry| | 570 | unit_off + reloc.source_off, |
| 569 | unit.header_len + unit.getEntry(source_entry).off | ||
| 570 | else | ||
| 571 | 0) + reloc.source_off, | ||
| 572 | target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry| | 571 | target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry| |
| 573 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off | 572 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off |
| 574 | else | 573 | else |
| ... | @@ -576,57 +575,8 @@ const Unit = struct { | ... | @@ -576,57 +575,8 @@ const Unit = struct { |
| 576 | dwarf.sectionOffsetBytes(), | 575 | dwarf.sectionOffsetBytes(), |
| 577 | ); | 576 | ); |
| 578 | } | 577 | } |
| 579 | if (dwarf.bin_file.cast(.elf)) |elf_file| { | 578 | for (unit.entries.items) |*entry| try entry.resolveRelocs(unit, sec, dwarf); |
| 580 | const zo = elf_file.zigObjectPtr().?; | ||
| 581 | for (unit.external_relocs.items) |reloc| { | ||
| 582 | const symbol = zo.symbol(reloc.target_sym); | ||
| 583 | try dwarf.resolveReloc( | ||
| 584 | sec.off + unit.off + unit.header_len + unit.getEntry(reloc.source_entry).off + reloc.source_off, | ||
| 585 | @bitCast(symbol.address(.{}, elf_file) + @as(i64, @intCast(reloc.target_off)) - | ||
| 586 | if (symbol.flags.is_tls) elf_file.dtpAddress() else 0), | ||
| 587 | @intFromEnum(dwarf.address_size), | ||
| 588 | ); | ||
| 589 | } | ||
| 590 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { | ||
| 591 | const zo = macho_file.getZigObject().?; | ||
| 592 | for (unit.external_relocs.items) |reloc| { | ||
| 593 | const ref = zo.getSymbolRef(reloc.target_sym, macho_file); | ||
| 594 | try dwarf.resolveReloc( | ||
| 595 | sec.off + unit.off + unit.header_len + unit.getEntry(reloc.source_entry).off + reloc.source_off, | ||
| 596 | ref.getSymbol(macho_file).?.getAddress(.{}, macho_file), | ||
| 597 | @intFromEnum(dwarf.address_size), | ||
| 598 | ); | ||
| 599 | } | ||
| 600 | } | ||
| 601 | } | 579 | } |
| 602 | |||
| 603 | const CrossEntryReloc = struct { | ||
| 604 | source_entry: Entry.Index.Optional = .none, | ||
| 605 | source_off: u32 = 0, | ||
| 606 | target_entry: Entry.Index, | ||
| 607 | target_off: u32 = 0, | ||
| 608 | }; | ||
| 609 | const CrossUnitReloc = struct { | ||
| 610 | source_entry: Entry.Index.Optional = .none, | ||
| 611 | source_off: u32 = 0, | ||
| 612 | target_unit: Unit.Index, | ||
| 613 | target_entry: Entry.Index.Optional = .none, | ||
| 614 | target_off: u32 = 0, | ||
| 615 | }; | ||
| 616 | const CrossSectionReloc = struct { | ||
| 617 | source_entry: Entry.Index.Optional = .none, | ||
| 618 | source_off: u32 = 0, | ||
| 619 | target_sec: Section.Index, | ||
| 620 | target_unit: Unit.Index, | ||
| 621 | target_entry: Entry.Index.Optional = .none, | ||
| 622 | target_off: u32 = 0, | ||
| 623 | }; | ||
| 624 | const ExternalReloc = struct { | ||
| 625 | source_entry: Entry.Index, | ||
| 626 | source_off: u32 = 0, | ||
| 627 | target_sym: u32, | ||
| 628 | target_off: u64 = 0, | ||
| 629 | }; | ||
| 630 | }; | 580 | }; |
| 631 | 581 | ||
| 632 | /// An indivisible entry within a `Unit` containing section-specific data. | 582 | /// An indivisible entry within a `Unit` containing section-specific data. |
| ... | @@ -637,6 +587,25 @@ const Entry = struct { | ... | @@ -637,6 +587,25 @@ const Entry = struct { |
| 637 | off: u32, | 587 | off: u32, |
| 638 | /// data length in bytes | 588 | /// data length in bytes |
| 639 | len: u32, | 589 | len: u32, |
| 590 | cross_entry_relocs: std.ArrayListUnmanaged(CrossEntryReloc), | ||
| 591 | cross_unit_relocs: std.ArrayListUnmanaged(CrossUnitReloc), | ||
| 592 | cross_section_relocs: std.ArrayListUnmanaged(CrossSectionReloc), | ||
| 593 | external_relocs: std.ArrayListUnmanaged(ExternalReloc), | ||
| 594 | |||
| 595 | fn clear(entry: *Entry) void { | ||
| 596 | entry.cross_entry_relocs.clearRetainingCapacity(); | ||
| 597 | entry.cross_unit_relocs.clearRetainingCapacity(); | ||
| 598 | entry.cross_section_relocs.clearRetainingCapacity(); | ||
| 599 | entry.external_relocs.clearRetainingCapacity(); | ||
| 600 | } | ||
| 601 | |||
| 602 | fn deinit(entry: *Entry, gpa: std.mem.Allocator) void { | ||
| 603 | entry.cross_entry_relocs.deinit(gpa); | ||
| 604 | entry.cross_unit_relocs.deinit(gpa); | ||
| 605 | entry.cross_section_relocs.deinit(gpa); | ||
| 606 | entry.external_relocs.deinit(gpa); | ||
| 607 | entry.* = undefined; | ||
| 608 | } | ||
| 640 | 609 | ||
| 641 | const Index = enum(u32) { | 610 | const Index = enum(u32) { |
| 642 | _, | 611 | _, |
| ... | @@ -803,6 +772,88 @@ const Entry = struct { | ... | @@ -803,6 +772,88 @@ const Entry = struct { |
| 803 | } | 772 | } |
| 804 | @panic("missing dwarf relocation target"); | 773 | @panic("missing dwarf relocation target"); |
| 805 | } | 774 | } |
| 775 | |||
| 776 | fn resolveRelocs(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void { | ||
| 777 | const entry_off = sec.off + unit.off + unit.header_len + entry.off; | ||
| 778 | for (entry.cross_entry_relocs.items) |reloc| { | ||
| 779 | try dwarf.resolveReloc( | ||
| 780 | entry_off + reloc.source_off, | ||
| 781 | unit.off + unit.header_len + unit.getEntry(reloc.target_entry).assertNonEmpty(unit, sec, dwarf).off + reloc.target_off, | ||
| 782 | dwarf.sectionOffsetBytes(), | ||
| 783 | ); | ||
| 784 | } | ||
| 785 | for (entry.cross_unit_relocs.items) |reloc| { | ||
| 786 | const target_unit = sec.getUnit(reloc.target_unit); | ||
| 787 | try dwarf.resolveReloc( | ||
| 788 | entry_off + reloc.source_off, | ||
| 789 | target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry| | ||
| 790 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off | ||
| 791 | else | ||
| 792 | 0) + reloc.target_off, | ||
| 793 | dwarf.sectionOffsetBytes(), | ||
| 794 | ); | ||
| 795 | } | ||
| 796 | for (entry.cross_section_relocs.items) |reloc| { | ||
| 797 | const target_sec = switch (reloc.target_sec) { | ||
| 798 | inline else => |target_sec| &@field(dwarf, @tagName(target_sec)).section, | ||
| 799 | }; | ||
| 800 | const target_unit = target_sec.getUnit(reloc.target_unit); | ||
| 801 | try dwarf.resolveReloc( | ||
| 802 | entry_off + reloc.source_off, | ||
| 803 | target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry| | ||
| 804 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off | ||
| 805 | else | ||
| 806 | 0) + reloc.target_off, | ||
| 807 | dwarf.sectionOffsetBytes(), | ||
| 808 | ); | ||
| 809 | } | ||
| 810 | if (dwarf.bin_file.cast(.elf)) |elf_file| { | ||
| 811 | const zo = elf_file.zigObjectPtr().?; | ||
| 812 | for (entry.external_relocs.items) |reloc| { | ||
| 813 | const symbol = zo.symbol(reloc.target_sym); | ||
| 814 | try dwarf.resolveReloc( | ||
| 815 | entry_off + reloc.source_off, | ||
| 816 | @bitCast(symbol.address(.{}, elf_file) + @as(i64, @intCast(reloc.target_off)) - | ||
| 817 | if (symbol.flags.is_tls) elf_file.dtpAddress() else 0), | ||
| 818 | @intFromEnum(dwarf.address_size), | ||
| 819 | ); | ||
| 820 | } | ||
| 821 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { | ||
| 822 | const zo = macho_file.getZigObject().?; | ||
| 823 | for (entry.external_relocs.items) |reloc| { | ||
| 824 | const ref = zo.getSymbolRef(reloc.target_sym, macho_file); | ||
| 825 | try dwarf.resolveReloc( | ||
| 826 | entry_off + reloc.source_off, | ||
| 827 | ref.getSymbol(macho_file).?.getAddress(.{}, macho_file), | ||
| 828 | @intFromEnum(dwarf.address_size), | ||
| 829 | ); | ||
| 830 | } | ||
| 831 | } | ||
| 832 | } | ||
| 833 | }; | ||
| 834 | |||
| 835 | const CrossEntryReloc = struct { | ||
| 836 | source_off: u32 = 0, | ||
| 837 | target_entry: Entry.Index, | ||
| 838 | target_off: u32 = 0, | ||
| 839 | }; | ||
| 840 | const CrossUnitReloc = struct { | ||
| 841 | source_off: u32 = 0, | ||
| 842 | target_unit: Unit.Index, | ||
| 843 | target_entry: Entry.Index.Optional = .none, | ||
| 844 | target_off: u32 = 0, | ||
| 845 | }; | ||
| 846 | const CrossSectionReloc = struct { | ||
| 847 | source_off: u32 = 0, | ||
| 848 | target_sec: Section.Index, | ||
| 849 | target_unit: Unit.Index, | ||
| 850 | target_entry: Entry.Index.Optional = .none, | ||
| 851 | target_off: u32 = 0, | ||
| 852 | }; | ||
| 853 | const ExternalReloc = struct { | ||
| 854 | source_off: u32 = 0, | ||
| 855 | target_sym: u32, | ||
| 856 | target_off: u64 = 0, | ||
| 806 | }; | 857 | }; |
| 807 | 858 | ||
| 808 | pub const Loc = union(enum) { | 859 | pub const Loc = union(enum) { |
| ... | @@ -986,7 +1037,9 @@ pub const WipNav = struct { | ... | @@ -986,7 +1037,9 @@ pub const WipNav = struct { |
| 986 | entry: Entry.Index, | 1037 | entry: Entry.Index, |
| 987 | any_children: bool, | 1038 | any_children: bool, |
| 988 | func: InternPool.Index, | 1039 | func: InternPool.Index, |
| 1040 | func_sym_index: u32, | ||
| 989 | func_high_reloc: u32, | 1041 | func_high_reloc: u32, |
| 1042 | inlined_funcs_high_reloc: std.ArrayListUnmanaged(u32), | ||
| 990 | debug_info: std.ArrayListUnmanaged(u8), | 1043 | debug_info: std.ArrayListUnmanaged(u8), |
| 991 | debug_line: std.ArrayListUnmanaged(u8), | 1044 | debug_line: std.ArrayListUnmanaged(u8), |
| 992 | debug_loclists: std.ArrayListUnmanaged(u8), | 1045 | debug_loclists: std.ArrayListUnmanaged(u8), |
| ... | @@ -994,6 +1047,7 @@ pub const WipNav = struct { | ... | @@ -994,6 +1047,7 @@ pub const WipNav = struct { |
| 994 | 1047 | ||
| 995 | pub fn deinit(wip_nav: *WipNav) void { | 1048 | pub fn deinit(wip_nav: *WipNav) void { |
| 996 | const gpa = wip_nav.dwarf.gpa; | 1049 | const gpa = wip_nav.dwarf.gpa; |
| 1050 | if (wip_nav.func != .none) wip_nav.inlined_funcs_high_reloc.deinit(gpa); | ||
| 997 | wip_nav.debug_info.deinit(gpa); | 1051 | wip_nav.debug_info.deinit(gpa); |
| 998 | wip_nav.debug_line.deinit(gpa); | 1052 | wip_nav.debug_line.deinit(gpa); |
| 999 | wip_nav.debug_loclists.deinit(gpa); | 1053 | wip_nav.debug_loclists.deinit(gpa); |
| ... | @@ -1004,10 +1058,10 @@ pub const WipNav = struct { | ... | @@ -1004,10 +1058,10 @@ pub const WipNav = struct { |
| 1004 | return wip_nav.debug_info.writer(wip_nav.dwarf.gpa); | 1058 | return wip_nav.debug_info.writer(wip_nav.dwarf.gpa); |
| 1005 | } | 1059 | } |
| 1006 | 1060 | ||
| 1007 | pub const VarTag = enum { local_arg, local_var }; | 1061 | pub const LocalTag = enum { local_arg, local_var }; |
| 1008 | pub fn genVarDebugInfo( | 1062 | pub fn genLocalDebugInfo( |
| 1009 | wip_nav: *WipNav, | 1063 | wip_nav: *WipNav, |
| 1010 | tag: VarTag, | 1064 | tag: LocalTag, |
| 1011 | name: []const u8, | 1065 | name: []const u8, |
| 1012 | ty: Type, | 1066 | ty: Type, |
| 1013 | loc: Loc, | 1067 | loc: Loc, |
| ... | @@ -1078,7 +1132,43 @@ pub const WipNav = struct { | ... | @@ -1078,7 +1132,43 @@ pub const WipNav = struct { |
| 1078 | try dlw.writeByte(DW.LNS.set_epilogue_begin); | 1132 | try dlw.writeByte(DW.LNS.set_epilogue_begin); |
| 1079 | } | 1133 | } |
| 1080 | 1134 | ||
| 1135 | pub fn enterInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64, line: u32, column: u32) UpdateError!void { | ||
| 1136 | const dwarf = wip_nav.dwarf; | ||
| 1137 | const zcu = wip_nav.pt.zcu; | ||
| 1138 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | ||
| 1139 | try wip_nav.inlined_funcs_high_reloc.ensureUnusedCapacity(dwarf.gpa, 1); | ||
| 1140 | |||
| 1141 | try uleb128(diw, @intFromEnum(AbbrevCode.inlined_func)); | ||
| 1142 | try wip_nav.refNav(zcu.funcInfo(func).owner_nav); | ||
| 1143 | try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1); | ||
| 1144 | try uleb128(diw, column + 1); | ||
| 1145 | const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs; | ||
| 1146 | try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2); | ||
| 1147 | external_relocs.appendAssumeCapacity(.{ | ||
| 1148 | .source_off = @intCast(wip_nav.debug_info.items.len), | ||
| 1149 | .target_sym = wip_nav.func_sym_index, | ||
| 1150 | .target_off = code_off, | ||
| 1151 | }); | ||
| 1152 | try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); | ||
| 1153 | wip_nav.inlined_funcs_high_reloc.appendAssumeCapacity(@intCast(external_relocs.items.len)); | ||
| 1154 | external_relocs.appendAssumeCapacity(.{ | ||
| 1155 | .source_off = @intCast(wip_nav.debug_info.items.len), | ||
| 1156 | .target_sym = wip_nav.func_sym_index, | ||
| 1157 | .target_off = undefined, | ||
| 1158 | }); | ||
| 1159 | try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); | ||
| 1160 | try wip_nav.setInlineFunc(func); | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void { | ||
| 1164 | const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs; | ||
| 1165 | external_relocs.items[wip_nav.inlined_funcs_high_reloc.pop()].target_off = code_off; | ||
| 1166 | try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null)); | ||
| 1167 | try wip_nav.setInlineFunc(func); | ||
| 1168 | } | ||
| 1169 | |||
| 1081 | pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void { | 1170 | pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void { |
| 1171 | wip_nav.any_children = true; | ||
| 1082 | const zcu = wip_nav.pt.zcu; | 1172 | const zcu = wip_nav.pt.zcu; |
| 1083 | const dwarf = wip_nav.dwarf; | 1173 | const dwarf = wip_nav.dwarf; |
| 1084 | if (wip_nav.func == func) return; | 1174 | if (wip_nav.func == func) return; |
| ... | @@ -1096,8 +1186,7 @@ pub const WipNav = struct { | ... | @@ -1096,8 +1186,7 @@ pub const WipNav = struct { |
| 1096 | try dlw.writeByte(DW.LNS.extended_op); | 1186 | try dlw.writeByte(DW.LNS.extended_op); |
| 1097 | try uleb128(dlw, 1 + dwarf.sectionOffsetBytes()); | 1187 | try uleb128(dlw, 1 + dwarf.sectionOffsetBytes()); |
| 1098 | try dlw.writeByte(DW.LNE.ZIG_set_decl); | 1188 | try dlw.writeByte(DW.LNE.ZIG_set_decl); |
| 1099 | try dwarf.debug_line.section.getUnit(wip_nav.unit).cross_section_relocs.append(dwarf.gpa, .{ | 1189 | try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_section_relocs.append(dwarf.gpa, .{ |
| 1100 | .source_entry = wip_nav.entry.toOptional(), | ||
| 1101 | .source_off = @intCast(wip_nav.debug_line.items.len), | 1190 | .source_off = @intCast(wip_nav.debug_line.items.len), |
| 1102 | .target_sec = .debug_info, | 1191 | .target_sec = .debug_info, |
| 1103 | .target_unit = new_unit, | 1192 | .target_unit = new_unit, |
| ... | @@ -1133,9 +1222,9 @@ pub const WipNav = struct { | ... | @@ -1133,9 +1222,9 @@ pub const WipNav = struct { |
| 1133 | fn infoSectionOffset(wip_nav: *WipNav, sec: Section.Index, unit: Unit.Index, entry: Entry.Index, off: u32) UpdateError!void { | 1222 | fn infoSectionOffset(wip_nav: *WipNav, sec: Section.Index, unit: Unit.Index, entry: Entry.Index, off: u32) UpdateError!void { |
| 1134 | const dwarf = wip_nav.dwarf; | 1223 | const dwarf = wip_nav.dwarf; |
| 1135 | const gpa = dwarf.gpa; | 1224 | const gpa = dwarf.gpa; |
| 1225 | const entry_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry); | ||
| 1136 | if (sec != .debug_info) { | 1226 | if (sec != .debug_info) { |
| 1137 | try dwarf.debug_info.section.getUnit(wip_nav.unit).cross_section_relocs.append(gpa, .{ | 1227 | try entry_ptr.cross_section_relocs.append(gpa, .{ |
| 1138 | .source_entry = wip_nav.entry.toOptional(), | ||
| 1139 | .source_off = @intCast(wip_nav.debug_info.items.len), | 1228 | .source_off = @intCast(wip_nav.debug_info.items.len), |
| 1140 | .target_sec = sec, | 1229 | .target_sec = sec, |
| 1141 | .target_unit = unit, | 1230 | .target_unit = unit, |
| ... | @@ -1143,16 +1232,14 @@ pub const WipNav = struct { | ... | @@ -1143,16 +1232,14 @@ pub const WipNav = struct { |
| 1143 | .target_off = off, | 1232 | .target_off = off, |
| 1144 | }); | 1233 | }); |
| 1145 | } else if (unit != wip_nav.unit) { | 1234 | } else if (unit != wip_nav.unit) { |
| 1146 | try dwarf.debug_info.section.getUnit(wip_nav.unit).cross_unit_relocs.append(gpa, .{ | 1235 | try entry_ptr.cross_unit_relocs.append(gpa, .{ |
| 1147 | .source_entry = wip_nav.entry.toOptional(), | ||
| 1148 | .source_off = @intCast(wip_nav.debug_info.items.len), | 1236 | .source_off = @intCast(wip_nav.debug_info.items.len), |
| 1149 | .target_unit = unit, | 1237 | .target_unit = unit, |
| 1150 | .target_entry = entry.toOptional(), | 1238 | .target_entry = entry.toOptional(), |
| 1151 | .target_off = off, | 1239 | .target_off = off, |
| 1152 | }); | 1240 | }); |
| 1153 | } else { | 1241 | } else { |
| 1154 | try dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs.append(gpa, .{ | 1242 | try entry_ptr.cross_entry_relocs.append(gpa, .{ |
| 1155 | .source_entry = wip_nav.entry.toOptional(), | ||
| 1156 | .source_off = @intCast(wip_nav.debug_info.items.len), | 1243 | .source_off = @intCast(wip_nav.debug_info.items.len), |
| 1157 | .target_entry = entry, | 1244 | .target_entry = entry, |
| 1158 | .target_off = off, | 1245 | .target_off = off, |
| ... | @@ -1167,8 +1254,7 @@ pub const WipNav = struct { | ... | @@ -1167,8 +1254,7 @@ pub const WipNav = struct { |
| 1167 | 1254 | ||
| 1168 | fn addrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void { | 1255 | fn addrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void { |
| 1169 | const dwarf = wip_nav.dwarf; | 1256 | const dwarf = wip_nav.dwarf; |
| 1170 | try dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs.append(dwarf.gpa, .{ | 1257 | try dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{ |
| 1171 | .source_entry = wip_nav.entry, | ||
| 1172 | .source_off = @intCast(wip_nav.debug_info.items.len), | 1258 | .source_off = @intCast(wip_nav.debug_info.items.len), |
| 1173 | .target_sym = sym_index, | 1259 | .target_sym = sym_index, |
| 1174 | }); | 1260 | }); |
| ... | @@ -1217,12 +1303,20 @@ pub const WipNav = struct { | ... | @@ -1217,12 +1303,20 @@ pub const WipNav = struct { |
| 1217 | try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0); | 1303 | try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0); |
| 1218 | } | 1304 | } |
| 1219 | 1305 | ||
| 1306 | fn refNav(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!void { | ||
| 1307 | const zcu = wip_nav.pt.zcu; | ||
| 1308 | const ip = &zcu.intern_pool; | ||
| 1309 | const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod); | ||
| 1310 | const nav_gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index); | ||
| 1311 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try wip_nav.dwarf.addCommonEntry(unit); | ||
| 1312 | try wip_nav.infoSectionOffset(.debug_info, unit, nav_gop.value_ptr.*, 0); | ||
| 1313 | } | ||
| 1314 | |||
| 1220 | fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 { | 1315 | fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 { |
| 1221 | const dwarf = wip_nav.dwarf; | 1316 | const dwarf = wip_nav.dwarf; |
| 1222 | const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs; | 1317 | const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs; |
| 1223 | const reloc_index: u32 = @intCast(cross_entry_relocs.items.len); | 1318 | const reloc_index: u32 = @intCast(cross_entry_relocs.items.len); |
| 1224 | try cross_entry_relocs.append(dwarf.gpa, .{ | 1319 | try cross_entry_relocs.append(dwarf.gpa, .{ |
| 1225 | .source_entry = wip_nav.entry.toOptional(), | ||
| 1226 | .source_off = @intCast(wip_nav.debug_info.items.len), | 1320 | .source_off = @intCast(wip_nav.debug_info.items.len), |
| 1227 | .target_entry = undefined, | 1321 | .target_entry = undefined, |
| 1228 | .target_off = undefined, | 1322 | .target_off = undefined, |
| ... | @@ -1232,7 +1326,7 @@ pub const WipNav = struct { | ... | @@ -1232,7 +1326,7 @@ pub const WipNav = struct { |
| 1232 | } | 1326 | } |
| 1233 | 1327 | ||
| 1234 | fn finishForward(wip_nav: *WipNav, reloc_index: u32) void { | 1328 | fn finishForward(wip_nav: *WipNav, reloc_index: u32) void { |
| 1235 | const reloc = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs.items[reloc_index]; | 1329 | const reloc = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs.items[reloc_index]; |
| 1236 | reloc.target_entry = wip_nav.entry; | 1330 | reloc.target_entry = wip_nav.entry; |
| 1237 | reloc.target_off = @intCast(wip_nav.debug_info.items.len); | 1331 | reloc.target_off = @intCast(wip_nav.debug_info.items.len); |
| 1238 | } | 1332 | } |
| ... | @@ -1545,7 +1639,15 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1545,7 +1639,15 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1545 | const unit = try dwarf.getUnit(file.mod); | 1639 | const unit = try dwarf.getUnit(file.mod); |
| 1546 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); | 1640 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); |
| 1547 | errdefer _ = dwarf.navs.pop(); | 1641 | errdefer _ = dwarf.navs.pop(); |
| 1548 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 1642 | if (nav_gop.found_existing) { |
| 1643 | for ([_]*Section{ | ||
| 1644 | &dwarf.debug_aranges.section, | ||
| 1645 | &dwarf.debug_info.section, | ||
| 1646 | &dwarf.debug_line.section, | ||
| 1647 | &dwarf.debug_loclists.section, | ||
| 1648 | &dwarf.debug_rnglists.section, | ||
| 1649 | }) |sec| sec.getUnit(unit).getEntry(nav_gop.value_ptr.*).clear(); | ||
| 1650 | } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | ||
| 1549 | const nav_val = zcu.navValue(nav_index); | 1651 | const nav_val = zcu.navValue(nav_index); |
| 1550 | var wip_nav: WipNav = .{ | 1652 | var wip_nav: WipNav = .{ |
| 1551 | .dwarf = dwarf, | 1653 | .dwarf = dwarf, |
| ... | @@ -1554,7 +1656,9 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1554,7 +1656,9 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1554 | .entry = nav_gop.value_ptr.*, | 1656 | .entry = nav_gop.value_ptr.*, |
| 1555 | .any_children = false, | 1657 | .any_children = false, |
| 1556 | .func = .none, | 1658 | .func = .none, |
| 1659 | .func_sym_index = undefined, | ||
| 1557 | .func_high_reloc = undefined, | 1660 | .func_high_reloc = undefined, |
| 1661 | .inlined_funcs_high_reloc = undefined, | ||
| 1558 | .debug_info = .{}, | 1662 | .debug_info = .{}, |
| 1559 | .debug_line = .{}, | 1663 | .debug_line = .{}, |
| 1560 | .debug_loclists = .{}, | 1664 | .debug_loclists = .{}, |
| ... | @@ -1608,16 +1712,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1608,16 +1712,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1608 | try wip_nav.exprloc(.{ .addr = .{ .sym = sym_index } }); | 1712 | try wip_nav.exprloc(.{ .addr = .{ .sym = sym_index } }); |
| 1609 | try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse | 1713 | try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse |
| 1610 | ty.abiAlignment(pt).toByteUnits().?); | 1714 | ty.abiAlignment(pt).toByteUnits().?); |
| 1611 | const func_unit = InternPool.AnalUnit.wrap(.{ .func = nav_val.toIntern() }); | 1715 | try diw.writeByte(@intFromBool(false)); |
| 1612 | try diw.writeByte(@intFromBool(for (if (zcu.single_exports.get(func_unit)) |export_index| | ||
| 1613 | zcu.all_exports.items[export_index..][0..1] | ||
| 1614 | else if (zcu.multi_exports.get(func_unit)) |export_range| | ||
| 1615 | zcu.all_exports.items[export_range.index..][0..export_range.len] | ||
| 1616 | else | ||
| 1617 | &.{}) |@"export"| | ||
| 1618 | { | ||
| 1619 | if (@"export".exported == .nav and @"export".exported.nav == nav_index) break true; | ||
| 1620 | } else false)); | ||
| 1621 | wip_nav.finishForward(ty_reloc_index); | 1716 | wip_nav.finishForward(ty_reloc_index); |
| 1622 | try uleb128(diw, @intFromEnum(AbbrevCode.is_const)); | 1717 | try uleb128(diw, @intFromEnum(AbbrevCode.is_const)); |
| 1623 | try wip_nav.refType(ty); | 1718 | try wip_nav.refType(ty); |
| ... | @@ -1668,16 +1763,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1668,16 +1763,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1668 | try wip_nav.exprloc(if (variable.is_threadlocal) .{ .form_tls_address = &addr } else addr); | 1763 | try wip_nav.exprloc(if (variable.is_threadlocal) .{ .form_tls_address = &addr } else addr); |
| 1669 | try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse | 1764 | try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse |
| 1670 | ty.abiAlignment(pt).toByteUnits().?); | 1765 | ty.abiAlignment(pt).toByteUnits().?); |
| 1671 | const func_unit = InternPool.AnalUnit.wrap(.{ .func = nav_val.toIntern() }); | 1766 | try diw.writeByte(@intFromBool(false)); |
| 1672 | try diw.writeByte(@intFromBool(for (if (zcu.single_exports.get(func_unit)) |export_index| | ||
| 1673 | zcu.all_exports.items[export_index..][0..1] | ||
| 1674 | else if (zcu.multi_exports.get(func_unit)) |export_range| | ||
| 1675 | zcu.all_exports.items[export_range.index..][0..export_range.len] | ||
| 1676 | else | ||
| 1677 | &.{}) |@"export"| | ||
| 1678 | { | ||
| 1679 | if (@"export".exported == .nav and @"export".exported.nav == nav_index) break true; | ||
| 1680 | } else false)); | ||
| 1681 | }, | 1767 | }, |
| 1682 | .func => |func| { | 1768 | .func => |func| { |
| 1683 | assert(file.zir_loaded); | 1769 | assert(file.zir_loaded); |
| ... | @@ -1712,6 +1798,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1712,6 +1798,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1712 | 1798 | ||
| 1713 | const func_type = ip.indexToKey(func.ty).func_type; | 1799 | const func_type = ip.indexToKey(func.ty).func_type; |
| 1714 | wip_nav.func = nav_val.toIntern(); | 1800 | wip_nav.func = nav_val.toIntern(); |
| 1801 | wip_nav.func_sym_index = sym_index; | ||
| 1802 | wip_nav.inlined_funcs_high_reloc = .{}; | ||
| 1715 | 1803 | ||
| 1716 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | 1804 | const diw = wip_nav.debug_info.writer(dwarf.gpa); |
| 1717 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_func)); | 1805 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_func)); |
| ... | @@ -1723,32 +1811,23 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1723,32 +1811,23 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1723 | try wip_nav.strp(nav.name.toSlice(ip)); | 1811 | try wip_nav.strp(nav.name.toSlice(ip)); |
| 1724 | try wip_nav.strp(nav.fqn.toSlice(ip)); | 1812 | try wip_nav.strp(nav.fqn.toSlice(ip)); |
| 1725 | try wip_nav.refType(Type.fromInterned(func_type.return_type)); | 1813 | try wip_nav.refType(Type.fromInterned(func_type.return_type)); |
| 1726 | const external_relocs = &dwarf.debug_info.section.getUnit(unit).external_relocs; | 1814 | const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs; |
| 1727 | try external_relocs.append(dwarf.gpa, .{ | 1815 | try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2); |
| 1728 | .source_entry = wip_nav.entry, | 1816 | external_relocs.appendAssumeCapacity(.{ |
| 1729 | .source_off = @intCast(wip_nav.debug_info.items.len), | 1817 | .source_off = @intCast(wip_nav.debug_info.items.len), |
| 1730 | .target_sym = sym_index, | 1818 | .target_sym = sym_index, |
| 1731 | }); | 1819 | }); |
| 1732 | try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); | 1820 | try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); |
| 1733 | wip_nav.func_high_reloc = @intCast(external_relocs.items.len); | 1821 | wip_nav.func_high_reloc = @intCast(external_relocs.items.len); |
| 1734 | try external_relocs.append(dwarf.gpa, .{ | 1822 | external_relocs.appendAssumeCapacity(.{ |
| 1735 | .source_entry = wip_nav.entry, | ||
| 1736 | .source_off = @intCast(wip_nav.debug_info.items.len), | 1823 | .source_off = @intCast(wip_nav.debug_info.items.len), |
| 1737 | .target_sym = sym_index, | 1824 | .target_sym = sym_index, |
| 1825 | .target_off = undefined, | ||
| 1738 | }); | 1826 | }); |
| 1739 | try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); | 1827 | try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); |
| 1740 | try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse | 1828 | try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse |
| 1741 | target_info.defaultFunctionAlignment(file.mod.resolved_target.result).toByteUnits().?); | 1829 | target_info.defaultFunctionAlignment(file.mod.resolved_target.result).toByteUnits().?); |
| 1742 | const func_unit = InternPool.AnalUnit.wrap(.{ .func = nav_val.toIntern() }); | 1830 | try diw.writeByte(@intFromBool(false)); |
| 1743 | try diw.writeByte(@intFromBool(for (if (zcu.single_exports.get(func_unit)) |export_index| | ||
| 1744 | zcu.all_exports.items[export_index..][0..1] | ||
| 1745 | else if (zcu.multi_exports.get(func_unit)) |export_range| | ||
| 1746 | zcu.all_exports.items[export_range.index..][0..export_range.len] | ||
| 1747 | else | ||
| 1748 | &.{}) |@"export"| | ||
| 1749 | { | ||
| 1750 | if (@"export".exported == .nav and @"export".exported.nav == nav_index) break true; | ||
| 1751 | } else false)); | ||
| 1752 | try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type)); | 1831 | try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type)); |
| 1753 | 1832 | ||
| 1754 | const dlw = wip_nav.debug_line.writer(dwarf.gpa); | 1833 | const dlw = wip_nav.debug_line.writer(dwarf.gpa); |
| ... | @@ -1756,8 +1835,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1756,8 +1835,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1756 | if (dwarf.incremental()) { | 1835 | if (dwarf.incremental()) { |
| 1757 | try uleb128(dlw, 1 + dwarf.sectionOffsetBytes()); | 1836 | try uleb128(dlw, 1 + dwarf.sectionOffsetBytes()); |
| 1758 | try dlw.writeByte(DW.LNE.ZIG_set_decl); | 1837 | try dlw.writeByte(DW.LNE.ZIG_set_decl); |
| 1759 | try dwarf.debug_line.section.getUnit(wip_nav.unit).cross_section_relocs.append(dwarf.gpa, .{ | 1838 | try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_section_relocs.append(dwarf.gpa, .{ |
| 1760 | .source_entry = wip_nav.entry.toOptional(), | ||
| 1761 | .source_off = @intCast(wip_nav.debug_line.items.len), | 1839 | .source_off = @intCast(wip_nav.debug_line.items.len), |
| 1762 | .target_sec = .debug_info, | 1840 | .target_sec = .debug_info, |
| 1763 | .target_unit = wip_nav.unit, | 1841 | .target_unit = wip_nav.unit, |
| ... | @@ -1772,8 +1850,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In | ... | @@ -1772,8 +1850,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In |
| 1772 | } else { | 1850 | } else { |
| 1773 | try uleb128(dlw, 1 + @intFromEnum(dwarf.address_size)); | 1851 | try uleb128(dlw, 1 + @intFromEnum(dwarf.address_size)); |
| 1774 | try dlw.writeByte(DW.LNE.set_address); | 1852 | try dlw.writeByte(DW.LNE.set_address); |
| 1775 | try dwarf.debug_line.section.getUnit(wip_nav.unit).external_relocs.append(dwarf.gpa, .{ | 1853 | try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{ |
| 1776 | .source_entry = wip_nav.entry, | ||
| 1777 | .source_off = @intCast(wip_nav.debug_line.items.len), | 1854 | .source_off = @intCast(wip_nav.debug_line.items.len), |
| 1778 | .target_sym = sym_index, | 1855 | .target_sym = sym_index, |
| 1779 | }); | 1856 | }); |
| ... | @@ -1806,7 +1883,8 @@ pub fn finishWipNav( | ... | @@ -1806,7 +1883,8 @@ pub fn finishWipNav( |
| 1806 | log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)}); | 1883 | log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)}); |
| 1807 | 1884 | ||
| 1808 | if (wip_nav.func != .none) { | 1885 | if (wip_nav.func != .none) { |
| 1809 | dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs.items[wip_nav.func_high_reloc].target_off = sym.size; | 1886 | const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs; |
| 1887 | external_relocs.items[wip_nav.func_high_reloc].target_off = sym.size; | ||
| 1810 | if (wip_nav.any_children) { | 1888 | if (wip_nav.any_children) { |
| 1811 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | 1889 | const diw = wip_nav.debug_info.writer(dwarf.gpa); |
| 1812 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | 1890 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); |
| ... | @@ -1817,8 +1895,7 @@ pub fn finishWipNav( | ... | @@ -1817,8 +1895,7 @@ pub fn finishWipNav( |
| 1817 | ); | 1895 | ); |
| 1818 | 1896 | ||
| 1819 | var aranges_entry = [1]u8{0} ** (8 + 8); | 1897 | var aranges_entry = [1]u8{0} ** (8 + 8); |
| 1820 | try dwarf.debug_aranges.section.getUnit(wip_nav.unit).external_relocs.append(dwarf.gpa, .{ | 1898 | try dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{ |
| 1821 | .source_entry = wip_nav.entry, | ||
| 1822 | .target_sym = sym.index, | 1899 | .target_sym = sym.index, |
| 1823 | }); | 1900 | }); |
| 1824 | dwarf.writeInt(aranges_entry[0..@intFromEnum(dwarf.address_size)], 0); | 1901 | dwarf.writeInt(aranges_entry[0..@intFromEnum(dwarf.address_size)], 0); |
| ... | @@ -1832,14 +1909,12 @@ pub fn finishWipNav( | ... | @@ -1832,14 +1909,12 @@ pub fn finishWipNav( |
| 1832 | aranges_entry[0 .. @intFromEnum(dwarf.address_size) * 2], | 1909 | aranges_entry[0 .. @intFromEnum(dwarf.address_size) * 2], |
| 1833 | ); | 1910 | ); |
| 1834 | 1911 | ||
| 1835 | try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).external_relocs.appendSlice(dwarf.gpa, &.{ | 1912 | try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.appendSlice(dwarf.gpa, &.{ |
| 1836 | .{ | 1913 | .{ |
| 1837 | .source_entry = wip_nav.entry, | ||
| 1838 | .source_off = 1, | 1914 | .source_off = 1, |
| 1839 | .target_sym = sym.index, | 1915 | .target_sym = sym.index, |
| 1840 | }, | 1916 | }, |
| 1841 | .{ | 1917 | .{ |
| 1842 | .source_entry = wip_nav.entry, | ||
| 1843 | .source_off = 1 + @intFromEnum(dwarf.address_size), | 1918 | .source_off = 1 + @intFromEnum(dwarf.address_size), |
| 1844 | .target_sym = sym.index, | 1919 | .target_sym = sym.index, |
| 1845 | .target_off = sym.size, | 1920 | .target_off = sym.size, |
| ... | @@ -1891,7 +1966,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -1891,7 +1966,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 1891 | .entry = undefined, | 1966 | .entry = undefined, |
| 1892 | .any_children = false, | 1967 | .any_children = false, |
| 1893 | .func = .none, | 1968 | .func = .none, |
| 1969 | .func_sym_index = undefined, | ||
| 1894 | .func_high_reloc = undefined, | 1970 | .func_high_reloc = undefined, |
| 1971 | .inlined_funcs_high_reloc = undefined, | ||
| 1895 | .debug_info = .{}, | 1972 | .debug_info = .{}, |
| 1896 | .debug_line = .{}, | 1973 | .debug_line = .{}, |
| 1897 | .debug_loclists = .{}, | 1974 | .debug_loclists = .{}, |
| ... | @@ -1902,6 +1979,62 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -1902,6 +1979,62 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 1902 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); | 1979 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); |
| 1903 | errdefer _ = dwarf.navs.pop(); | 1980 | errdefer _ = dwarf.navs.pop(); |
| 1904 | switch (ip.indexToKey(nav_val.toIntern())) { | 1981 | switch (ip.indexToKey(nav_val.toIntern())) { |
| 1982 | .func => |func| { | ||
| 1983 | if (nav_gop.found_existing) { | ||
| 1984 | const unit_ptr = dwarf.debug_info.section.getUnit(unit); | ||
| 1985 | const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*); | ||
| 1986 | if (entry_ptr.len >= AbbrevCode.decl_bytes) { | ||
| 1987 | var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined; | ||
| 1988 | if (try dwarf.getFile().?.preadAll( | ||
| 1989 | &abbrev_code_buf, | ||
| 1990 | dwarf.debug_info.section.off + unit_ptr.off + unit_ptr.header_len + entry_ptr.off, | ||
| 1991 | ) != abbrev_code_buf.len) return error.InputOutput; | ||
| 1992 | var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf); | ||
| 1993 | const abbrev_code: AbbrevCode = @enumFromInt( | ||
| 1994 | try std.leb.readUleb128(@typeInfo(AbbrevCode).Enum.tag_type, abbrev_code_fbs.reader()), | ||
| 1995 | ); | ||
| 1996 | switch (abbrev_code) { | ||
| 1997 | else => unreachable, | ||
| 1998 | .decl_func, .decl_func_empty => return, | ||
| 1999 | .decl_func_generic, .decl_func_generic_empty => {}, | ||
| 2000 | } | ||
| 2001 | } | ||
| 2002 | entry_ptr.clear(); | ||
| 2003 | } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | ||
| 2004 | wip_nav.entry = nav_gop.value_ptr.*; | ||
| 2005 | |||
| 2006 | const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { | ||
| 2007 | const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace); | ||
| 2008 | break :parent .{ | ||
| 2009 | parent_namespace_ptr.owner_type, | ||
| 2010 | if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu })) | ||
| 2011 | DW.ACCESS.public | ||
| 2012 | else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu })) | ||
| 2013 | DW.ACCESS.private | ||
| 2014 | else | ||
| 2015 | unreachable, | ||
| 2016 | }; | ||
| 2017 | } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; | ||
| 2018 | |||
| 2019 | const func_type = ip.indexToKey(func.ty).func_type; | ||
| 2020 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | ||
| 2021 | try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (func_type.param_types.len > 0 or func_type.is_var_args) .decl_func_generic else .decl_func_generic_empty))); | ||
| 2022 | try wip_nav.refType(Type.fromInterned(parent_type)); | ||
| 2023 | assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); | ||
| 2024 | try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); | ||
| 2025 | try uleb128(diw, loc.column + 1); | ||
| 2026 | try diw.writeByte(accessibility); | ||
| 2027 | try wip_nav.strp(nav.name.toSlice(ip)); | ||
| 2028 | try wip_nav.refType(Type.fromInterned(func_type.return_type)); | ||
| 2029 | if (func_type.param_types.len > 0 or func_type.is_var_args) { | ||
| 2030 | for (0..func_type.param_types.len) |param_index| { | ||
| 2031 | try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param)); | ||
| 2032 | try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index])); | ||
| 2033 | } | ||
| 2034 | if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args)); | ||
| 2035 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | ||
| 2036 | } | ||
| 2037 | }, | ||
| 1905 | .struct_type => done: { | 2038 | .struct_type => done: { |
| 1906 | const loaded_struct = ip.loadStructType(nav_val.toIntern()); | 2039 | const loaded_struct = ip.loadStructType(nav_val.toIntern()); |
| 1907 | 2040 | ||
| ... | @@ -2304,7 +2437,9 @@ fn updateType( | ... | @@ -2304,7 +2437,9 @@ fn updateType( |
| 2304 | .entry = dwarf.types.get(type_index).?, | 2437 | .entry = dwarf.types.get(type_index).?, |
| 2305 | .any_children = false, | 2438 | .any_children = false, |
| 2306 | .func = .none, | 2439 | .func = .none, |
| 2440 | .func_sym_index = undefined, | ||
| 2307 | .func_high_reloc = undefined, | 2441 | .func_high_reloc = undefined, |
| 2442 | .inlined_funcs_high_reloc = undefined, | ||
| 2308 | .debug_info = .{}, | 2443 | .debug_info = .{}, |
| 2309 | .debug_line = .{}, | 2444 | .debug_line = .{}, |
| 2310 | .debug_loclists = .{}, | 2445 | .debug_loclists = .{}, |
| ... | @@ -2467,13 +2602,25 @@ fn updateType( | ... | @@ -2467,13 +2602,25 @@ fn updateType( |
| 2467 | .error_union_type => |error_union_type| { | 2602 | .error_union_type => |error_union_type| { |
| 2468 | const error_union_error_set_type = Type.fromInterned(error_union_type.error_set_type); | 2603 | const error_union_error_set_type = Type.fromInterned(error_union_type.error_set_type); |
| 2469 | const error_union_payload_type = Type.fromInterned(error_union_type.payload_type); | 2604 | const error_union_payload_type = Type.fromInterned(error_union_type.payload_type); |
| 2470 | const error_union_error_set_offset = codegen.errUnionErrorOffset(error_union_payload_type, pt); | 2605 | const error_union_error_set_offset, const error_union_payload_offset = switch (error_union_type.payload_type) { |
| 2471 | const error_union_payload_offset = codegen.errUnionPayloadOffset(error_union_payload_type, pt); | 2606 | .generic_poison_type => .{ 0, 0 }, |
| 2607 | else => .{ | ||
| 2608 | codegen.errUnionErrorOffset(error_union_payload_type, pt), | ||
| 2609 | codegen.errUnionPayloadOffset(error_union_payload_type, pt), | ||
| 2610 | }, | ||
| 2611 | }; | ||
| 2472 | 2612 | ||
| 2473 | try uleb128(diw, @intFromEnum(AbbrevCode.union_type)); | 2613 | try uleb128(diw, @intFromEnum(AbbrevCode.union_type)); |
| 2474 | try wip_nav.strp(name); | 2614 | try wip_nav.strp(name); |
| 2475 | try uleb128(diw, ty.abiSize(pt)); | 2615 | if (error_union_type.error_set_type != .generic_poison_type and |
| 2476 | try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?); | 2616 | error_union_type.payload_type != .generic_poison_type) |
| 2617 | { | ||
| 2618 | try uleb128(diw, ty.abiSize(pt)); | ||
| 2619 | try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?); | ||
| 2620 | } else { | ||
| 2621 | try uleb128(diw, 0); | ||
| 2622 | try uleb128(diw, 1); | ||
| 2623 | } | ||
| 2477 | { | 2624 | { |
| 2478 | try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union)); | 2625 | try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union)); |
| 2479 | try wip_nav.infoSectionOffset( | 2626 | try wip_nav.infoSectionOffset( |
| ... | @@ -2655,10 +2802,16 @@ fn updateType( | ... | @@ -2655,10 +2802,16 @@ fn updateType( |
| 2655 | } | 2802 | } |
| 2656 | if (error_set_type.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null)); | 2803 | if (error_set_type.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null)); |
| 2657 | }, | 2804 | }, |
| 2658 | .inferred_error_set_type => |func| { | 2805 | .inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) { |
| 2659 | try uleb128(diw, @intFromEnum(AbbrevCode.inferred_error_set_type)); | 2806 | .none => { |
| 2660 | try wip_nav.strp(name); | 2807 | try uleb128(diw, @intFromEnum(AbbrevCode.void_type)); |
| 2661 | try wip_nav.refType(Type.fromInterned(ip.funcIesResolvedUnordered(func))); | 2808 | try wip_nav.strp(name); |
| 2809 | }, | ||
| 2810 | else => |ies| { | ||
| 2811 | try uleb128(diw, @intFromEnum(AbbrevCode.inferred_error_set_type)); | ||
| 2812 | try wip_nav.strp(name); | ||
| 2813 | try wip_nav.refType(Type.fromInterned(ies)); | ||
| 2814 | }, | ||
| 2662 | }, | 2815 | }, |
| 2663 | 2816 | ||
| 2664 | // values, not types | 2817 | // values, not types |
| ... | @@ -2705,7 +2858,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP | ... | @@ -2705,7 +2858,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP |
| 2705 | .entry = type_gop.value_ptr.*, | 2858 | .entry = type_gop.value_ptr.*, |
| 2706 | .any_children = false, | 2859 | .any_children = false, |
| 2707 | .func = .none, | 2860 | .func = .none, |
| 2861 | .func_sym_index = undefined, | ||
| 2708 | .func_high_reloc = undefined, | 2862 | .func_high_reloc = undefined, |
| 2863 | .inlined_funcs_high_reloc = undefined, | ||
| 2709 | .debug_info = .{}, | 2864 | .debug_info = .{}, |
| 2710 | .debug_line = .{}, | 2865 | .debug_line = .{}, |
| 2711 | .debug_loclists = .{}, | 2866 | .debug_loclists = .{}, |
| ... | @@ -2766,7 +2921,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP | ... | @@ -2766,7 +2921,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP |
| 2766 | .entry = type_gop.value_ptr.*, | 2921 | .entry = type_gop.value_ptr.*, |
| 2767 | .any_children = false, | 2922 | .any_children = false, |
| 2768 | .func = .none, | 2923 | .func = .none, |
| 2924 | .func_sym_index = undefined, | ||
| 2769 | .func_high_reloc = undefined, | 2925 | .func_high_reloc = undefined, |
| 2926 | .inlined_funcs_high_reloc = undefined, | ||
| 2770 | .debug_info = .{}, | 2927 | .debug_info = .{}, |
| 2771 | .debug_line = .{}, | 2928 | .debug_line = .{}, |
| 2772 | .debug_loclists = .{}, | 2929 | .debug_loclists = .{}, |
| ... | @@ -2940,7 +3097,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -2940,7 +3097,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 2940 | .entry = entry, | 3097 | .entry = entry, |
| 2941 | .any_children = false, | 3098 | .any_children = false, |
| 2942 | .func = .none, | 3099 | .func = .none, |
| 3100 | .func_sym_index = undefined, | ||
| 2943 | .func_high_reloc = undefined, | 3101 | .func_high_reloc = undefined, |
| 3102 | .inlined_funcs_high_reloc = undefined, | ||
| 2944 | .debug_info = .{}, | 3103 | .debug_info = .{}, |
| 2945 | .debug_line = .{}, | 3104 | .debug_line = .{}, |
| 2946 | .debug_loclists = .{}, | 3105 | .debug_loclists = .{}, |
| ... | @@ -2998,7 +3157,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -2998,7 +3157,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 2998 | if (dwarf.debug_aranges.section.dirty) { | 3157 | if (dwarf.debug_aranges.section.dirty) { |
| 2999 | for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| { | 3158 | for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| { |
| 3000 | const unit: Unit.Index = @enumFromInt(unit_index); | 3159 | const unit: Unit.Index = @enumFromInt(unit_index); |
| 3001 | try unit_ptr.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 1); | 3160 | unit_ptr.clear(); |
| 3161 | try unit_ptr.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 1); | ||
| 3002 | header.clearRetainingCapacity(); | 3162 | header.clearRetainingCapacity(); |
| 3003 | try header.ensureTotalCapacity(unit_ptr.header_len); | 3163 | try header.ensureTotalCapacity(unit_ptr.header_len); |
| 3004 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| | 3164 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| |
| ... | @@ -3029,8 +3189,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -3029,8 +3189,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 3029 | if (dwarf.debug_info.section.dirty) { | 3189 | if (dwarf.debug_info.section.dirty) { |
| 3030 | for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_info.section.units.items, 0..) |mod, mod_info, *unit_ptr, unit_index| { | 3190 | for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_info.section.units.items, 0..) |mod, mod_info, *unit_ptr, unit_index| { |
| 3031 | const unit: Unit.Index = @enumFromInt(unit_index); | 3191 | const unit: Unit.Index = @enumFromInt(unit_index); |
| 3032 | try unit_ptr.cross_unit_relocs.ensureUnusedCapacity(dwarf.gpa, 1); | 3192 | unit_ptr.clear(); |
| 3033 | try unit_ptr.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 7); | 3193 | try unit_ptr.cross_unit_relocs.ensureTotalCapacity(dwarf.gpa, 1); |
| 3194 | try unit_ptr.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 7); | ||
| 3034 | header.clearRetainingCapacity(); | 3195 | header.clearRetainingCapacity(); |
| 3035 | try header.ensureTotalCapacity(unit_ptr.header_len); | 3196 | try header.ensureTotalCapacity(unit_ptr.header_len); |
| 3036 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| | 3197 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| |
| ... | @@ -3121,7 +3282,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -3121,7 +3282,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 3121 | for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| | 3282 | for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| |
| 3122 | try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count()))); | 3283 | try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count()))); |
| 3123 | for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| { | 3284 | for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| { |
| 3124 | try unit.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count())); | 3285 | unit.clear(); |
| 3286 | try unit.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count())); | ||
| 3125 | header.clearRetainingCapacity(); | 3287 | header.clearRetainingCapacity(); |
| 3126 | try header.ensureTotalCapacity(unit.header_len); | 3288 | try header.ensureTotalCapacity(unit.header_len); |
| 3127 | const unit_len = (if (unit.next.unwrap()) |next_unit| | 3289 | const unit_len = (if (unit.next.unwrap()) |next_unit| |
| ... | @@ -3310,6 +3472,8 @@ const AbbrevCode = enum(u8) { | ... | @@ -3310,6 +3472,8 @@ const AbbrevCode = enum(u8) { |
| 3310 | decl_var, | 3472 | decl_var, |
| 3311 | decl_func, | 3473 | decl_func, |
| 3312 | decl_func_empty, | 3474 | decl_func_empty, |
| 3475 | decl_func_generic, | ||
| 3476 | decl_func_generic_empty, | ||
| 3313 | // the rest are unrestricted | 3477 | // the rest are unrestricted |
| 3314 | compile_unit, | 3478 | compile_unit, |
| 3315 | module, | 3479 | module, |
| ... | @@ -3344,10 +3508,11 @@ const AbbrevCode = enum(u8) { | ... | @@ -3344,10 +3508,11 @@ const AbbrevCode = enum(u8) { |
| 3344 | struct_type, | 3508 | struct_type, |
| 3345 | packed_struct_type, | 3509 | packed_struct_type, |
| 3346 | union_type, | 3510 | union_type, |
| 3511 | inlined_func, | ||
| 3347 | local_arg, | 3512 | local_arg, |
| 3348 | local_var, | 3513 | local_var, |
| 3349 | 3514 | ||
| 3350 | const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_empty)); | 3515 | const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_generic_empty)); |
| 3351 | 3516 | ||
| 3352 | const Attr = struct { | 3517 | const Attr = struct { |
| 3353 | DeclValEnum(DW.AT), | 3518 | DeclValEnum(DW.AT), |
| ... | @@ -3451,6 +3616,19 @@ const AbbrevCode = enum(u8) { | ... | @@ -3451,6 +3616,19 @@ const AbbrevCode = enum(u8) { |
| 3451 | .{ .noreturn, .flag }, | 3616 | .{ .noreturn, .flag }, |
| 3452 | }, | 3617 | }, |
| 3453 | }, | 3618 | }, |
| 3619 | .decl_func_generic = .{ | ||
| 3620 | .tag = .subprogram, | ||
| 3621 | .children = true, | ||
| 3622 | .attrs = decl_abbrev_common_attrs ++ .{ | ||
| 3623 | .{ .type, .ref_addr }, | ||
| 3624 | }, | ||
| 3625 | }, | ||
| 3626 | .decl_func_generic_empty = .{ | ||
| 3627 | .tag = .subprogram, | ||
| 3628 | .attrs = decl_abbrev_common_attrs ++ .{ | ||
| 3629 | .{ .type, .ref_addr }, | ||
| 3630 | }, | ||
| 3631 | }, | ||
| 3454 | .compile_unit = .{ | 3632 | .compile_unit = .{ |
| 3455 | .tag = .compile_unit, | 3633 | .tag = .compile_unit, |
| 3456 | .children = true, | 3634 | .children = true, |
| ... | @@ -3706,6 +3884,17 @@ const AbbrevCode = enum(u8) { | ... | @@ -3706,6 +3884,17 @@ const AbbrevCode = enum(u8) { |
| 3706 | .{ .alignment, .udata }, | 3884 | .{ .alignment, .udata }, |
| 3707 | }, | 3885 | }, |
| 3708 | }, | 3886 | }, |
| 3887 | .inlined_func = .{ | ||
| 3888 | .tag = .inlined_subroutine, | ||
| 3889 | .children = true, | ||
| 3890 | .attrs = &.{ | ||
| 3891 | .{ .abstract_origin, .ref_addr }, | ||
| 3892 | .{ .call_line, .udata }, | ||
| 3893 | .{ .call_column, .udata }, | ||
| 3894 | .{ .low_pc, .addr }, | ||
| 3895 | .{ .high_pc, .addr }, | ||
| 3896 | }, | ||
| 3897 | }, | ||
| 3709 | .local_arg = .{ | 3898 | .local_arg = .{ |
| 3710 | .tag = .formal_parameter, | 3899 | .tag = .formal_parameter, |
| 3711 | .attrs = &.{ | 3900 | .attrs = &.{ |
src/link/Elf/ZigObject.zig+6-6| ... | @@ -1122,9 +1122,9 @@ pub fn updateNav( | ... | @@ -1122,9 +1122,9 @@ pub fn updateNav( |
| 1122 | 1122 | ||
| 1123 | log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index }); | 1123 | log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index }); |
| 1124 | 1124 | ||
| 1125 | const nav_val = zcu.navValue(nav_index); | 1125 | const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) { |
| 1126 | const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { | 1126 | .func => .none, |
| 1127 | .variable => |variable| Value.fromInterned(variable.init), | 1127 | .variable => |variable| variable.init, |
| 1128 | .@"extern" => |@"extern"| { | 1128 | .@"extern" => |@"extern"| { |
| 1129 | if (ip.isFunctionType(@"extern".ty)) return; | 1129 | if (ip.isFunctionType(@"extern".ty)) return; |
| 1130 | const sym_index = try self.getGlobalSymbol( | 1130 | const sym_index = try self.getGlobalSymbol( |
| ... | @@ -1135,10 +1135,10 @@ pub fn updateNav( | ... | @@ -1135,10 +1135,10 @@ pub fn updateNav( |
| 1135 | self.symbol(sym_index).flags.is_extern_ptr = true; | 1135 | self.symbol(sym_index).flags.is_extern_ptr = true; |
| 1136 | return; | 1136 | return; |
| 1137 | }, | 1137 | }, |
| 1138 | else => nav_val, | 1138 | else => nav.status.resolved.val, |
| 1139 | }; | 1139 | }; |
| 1140 | 1140 | ||
| 1141 | if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) { | 1141 | if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) { |
| 1142 | const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index); | 1142 | const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index); |
| 1143 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); | 1143 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); |
| 1144 | 1144 | ||
| ... | @@ -1153,7 +1153,7 @@ pub fn updateNav( | ... | @@ -1153,7 +1153,7 @@ pub fn updateNav( |
| 1153 | &elf_file.base, | 1153 | &elf_file.base, |
| 1154 | pt, | 1154 | pt, |
| 1155 | zcu.navSrcLoc(nav_index), | 1155 | zcu.navSrcLoc(nav_index), |
| 1156 | nav_init, | 1156 | Value.fromInterned(nav_init), |
| 1157 | &code_buffer, | 1157 | &code_buffer, |
| 1158 | if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, | 1158 | if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, |
| 1159 | .{ .parent_atom_index = sym_index }, | 1159 | .{ .parent_atom_index = sym_index }, |
src/link/MachO/ZigObject.zig+7-6| ... | @@ -869,10 +869,11 @@ pub fn updateNav( | ... | @@ -869,10 +869,11 @@ pub fn updateNav( |
| 869 | 869 | ||
| 870 | const zcu = pt.zcu; | 870 | const zcu = pt.zcu; |
| 871 | const ip = &zcu.intern_pool; | 871 | const ip = &zcu.intern_pool; |
| 872 | const nav = ip.getNav(nav_index); | ||
| 872 | 873 | ||
| 873 | const nav_val = zcu.navValue(nav_index); | 874 | const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) { |
| 874 | const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { | 875 | .func => .none, |
| 875 | .variable => |variable| Value.fromInterned(variable.init), | 876 | .variable => |variable| variable.init, |
| 876 | .@"extern" => |@"extern"| { | 877 | .@"extern" => |@"extern"| { |
| 877 | if (ip.isFunctionType(@"extern".ty)) return; | 878 | if (ip.isFunctionType(@"extern".ty)) return; |
| 878 | // Extern variable gets a __got entry only | 879 | // Extern variable gets a __got entry only |
| ... | @@ -883,10 +884,10 @@ pub fn updateNav( | ... | @@ -883,10 +884,10 @@ pub fn updateNav( |
| 883 | sym.flags.is_extern_ptr = true; | 884 | sym.flags.is_extern_ptr = true; |
| 884 | return; | 885 | return; |
| 885 | }, | 886 | }, |
| 886 | else => nav_val, | 887 | else => nav.status.resolved.val, |
| 887 | }; | 888 | }; |
| 888 | 889 | ||
| 889 | if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) { | 890 | if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) { |
| 890 | const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index); | 891 | const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index); |
| 891 | self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file); | 892 | self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file); |
| 892 | 893 | ||
| ... | @@ -900,7 +901,7 @@ pub fn updateNav( | ... | @@ -900,7 +901,7 @@ pub fn updateNav( |
| 900 | &macho_file.base, | 901 | &macho_file.base, |
| 901 | pt, | 902 | pt, |
| 902 | zcu.navSrcLoc(nav_index), | 903 | zcu.navSrcLoc(nav_index), |
| 903 | nav_init, | 904 | Value.fromInterned(nav_init), |
| 904 | &code_buffer, | 905 | &code_buffer, |
| 905 | if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, | 906 | if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, |
| 906 | .{ .parent_atom_index = sym_index }, | 907 | .{ .parent_atom_index = sym_index }, |
src/link/Plan9.zig+2-1| ... | @@ -448,6 +448,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -448,6 +448,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 448 | const nav = ip.getNav(nav_index); | 448 | const nav = ip.getNav(nav_index); |
| 449 | const nav_val = zcu.navValue(nav_index); | 449 | const nav_val = zcu.navValue(nav_index); |
| 450 | const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { | 450 | const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { |
| 451 | .func => return, | ||
| 451 | .variable => |variable| Value.fromInterned(variable.init), | 452 | .variable => |variable| Value.fromInterned(variable.init), |
| 452 | .@"extern" => { | 453 | .@"extern" => { |
| 453 | log.debug("found extern decl: {}", .{nav.name.fmt(ip)}); | 454 | log.debug("found extern decl: {}", .{nav.name.fmt(ip)}); |
| ... | @@ -456,7 +457,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -456,7 +457,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 456 | else => nav_val, | 457 | else => nav_val, |
| 457 | }; | 458 | }; |
| 458 | 459 | ||
| 459 | if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) { | 460 | if (nav_init.typeOf(zcu).hasRuntimeBits(pt)) { |
| 460 | const atom_idx = try self.seeNav(pt, nav_index); | 461 | const atom_idx = try self.seeNav(pt, nav_index); |
| 461 | 462 | ||
| 462 | var code_buffer = std.ArrayList(u8).init(gpa); | 463 | var code_buffer = std.ArrayList(u8).init(gpa); |
src/link/Wasm/ZigObject.zig+1-1| ... | @@ -259,7 +259,7 @@ pub fn updateNav( | ... | @@ -259,7 +259,7 @@ pub fn updateNav( |
| 259 | else => .{ false, .none, nav_val }, | 259 | else => .{ false, .none, nav_val }, |
| 260 | }; | 260 | }; |
| 261 | 261 | ||
| 262 | if (nav_init.typeOf(zcu).isFnOrHasRuntimeBits(pt)) { | 262 | if (nav_init.typeOf(zcu).hasRuntimeBits(pt)) { |
| 263 | const gpa = wasm_file.base.comp.gpa; | 263 | const gpa = wasm_file.base.comp.gpa; |
| 264 | const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, nav_index); | 264 | const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, nav_index); |
| 265 | const atom = wasm_file.getAtomPtr(atom_index); | 265 | const atom = wasm_file.getAtomPtr(atom_index); |
src/print_air.zig+4-6| ... | @@ -283,6 +283,7 @@ const Writer = struct { | ... | @@ -283,6 +283,7 @@ const Writer = struct { |
| 283 | 283 | ||
| 284 | .dbg_var_ptr, | 284 | .dbg_var_ptr, |
| 285 | .dbg_var_val, | 285 | .dbg_var_val, |
| 286 | .dbg_arg_inline, | ||
| 286 | => try w.writeDbgVar(s, inst), | 287 | => try w.writeDbgVar(s, inst), |
| 287 | 288 | ||
| 288 | .struct_field_ptr => try w.writeStructField(s, inst), | 289 | .struct_field_ptr => try w.writeStructField(s, inst), |
| ... | @@ -358,10 +359,7 @@ const Writer = struct { | ... | @@ -358,10 +359,7 @@ const Writer = struct { |
| 358 | try w.writeType(s, arg.ty.toType()); | 359 | try w.writeType(s, arg.ty.toType()); |
| 359 | switch (arg.name) { | 360 | switch (arg.name) { |
| 360 | .none => {}, | 361 | .none => {}, |
| 361 | _ => { | 362 | _ => try s.print(", \"{}\"", .{std.zig.fmtEscapes(arg.name.toSlice(w.air))}), |
| 362 | const name = w.air.nullTerminatedString(@intFromEnum(arg.name)); | ||
| 363 | try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)}); | ||
| 364 | }, | ||
| 365 | } | 363 | } |
| 366 | } | 364 | } |
| 367 | 365 | ||
| ... | @@ -686,8 +684,8 @@ const Writer = struct { | ... | @@ -686,8 +684,8 @@ const Writer = struct { |
| 686 | fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 684 | fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 687 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 685 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 688 | try w.writeOperand(s, inst, 0, pl_op.operand); | 686 | try w.writeOperand(s, inst, 0, pl_op.operand); |
| 689 | const name = w.air.nullTerminatedString(pl_op.payload); | 687 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 690 | try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)}); | 688 | try s.print(", \"{}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))}); |
| 691 | } | 689 | } |
| 692 | 690 | ||
| 693 | fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 691 | fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
test/src/Debugger.zig+73-13| ... | @@ -587,7 +587,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { | ... | @@ -587,7 +587,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { |
| 587 | }, | 587 | }, |
| 588 | ); | 588 | ); |
| 589 | db.addLldbTest( | 589 | db.addLldbTest( |
| 590 | "cross_module_call", | 590 | "inline_call", |
| 591 | target, | 591 | target, |
| 592 | &.{ | 592 | &.{ |
| 593 | .{ | 593 | .{ |
| ... | @@ -595,8 +595,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { | ... | @@ -595,8 +595,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { |
| 595 | .source = | 595 | .source = |
| 596 | \\const module = @import("module"); | 596 | \\const module = @import("module"); |
| 597 | \\pub fn main() void { | 597 | \\pub fn main() void { |
| 598 | \\ module.foo(123); | 598 | \\ fa(12); |
| 599 | \\ module.bar(456); | 599 | \\ fb(34); |
| 600 | \\ module.fc(56); | ||
| 601 | \\ module.fd(78); | ||
| 602 | \\} | ||
| 603 | \\fn fa(pa: u32) void { | ||
| 604 | \\ const la = ~pa; | ||
| 605 | \\ _ = la; | ||
| 606 | \\} | ||
| 607 | \\inline fn fb(pb: u32) void { | ||
| 608 | \\ const lb = ~pb; | ||
| 609 | \\ _ = lb; | ||
| 600 | \\} | 610 | \\} |
| 601 | \\ | 611 | \\ |
| 602 | , | 612 | , |
| ... | @@ -605,34 +615,84 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { | ... | @@ -605,34 +615,84 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { |
| 605 | .import = "module", | 615 | .import = "module", |
| 606 | .path = "module.zig", | 616 | .path = "module.zig", |
| 607 | .source = | 617 | .source = |
| 608 | \\pub fn foo(x: u32) void { | 618 | \\pub fn fc(pc: u32) void { |
| 609 | \\ _ = x; | 619 | \\ const lc = ~pc; |
| 620 | \\ _ = lc; | ||
| 610 | \\} | 621 | \\} |
| 611 | \\pub inline fn bar(y: u32) void { | 622 | \\pub inline fn fd(pd: u32) void { |
| 612 | \\ _ = y; | 623 | \\ const ld = ~pd; |
| 624 | \\ _ = ld; | ||
| 613 | \\} | 625 | \\} |
| 614 | \\ | 626 | \\ |
| 615 | , | 627 | , |
| 616 | }, | 628 | }, |
| 617 | }, | 629 | }, |
| 618 | \\breakpoint set --file module.zig --source-pattern-regexp '_ = x;' | 630 | \\settings set frame-format 'frame #${frame.index}:{ ${module.file.basename}{\`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${line.file.basename}:${line.number}{:${line.column}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}\n' |
| 631 | \\ | ||
| 632 | \\breakpoint set --file main.zig --source-pattern-regexp '_ = la;' | ||
| 619 | \\process launch | 633 | \\process launch |
| 620 | \\source info | 634 | \\frame variable pa la |
| 635 | \\thread backtrace --count 2 | ||
| 621 | \\breakpoint delete --force 1 | 636 | \\breakpoint delete --force 1 |
| 622 | \\ | 637 | \\ |
| 623 | \\breakpoint set --file module.zig --line 5 | 638 | \\breakpoint set --file main.zig --source-pattern-regexp '_ = lb;' |
| 624 | \\process continue | 639 | \\process continue |
| 625 | \\source info | 640 | \\frame variable pb lb |
| 641 | \\thread backtrace --count 2 | ||
| 626 | \\breakpoint delete --force 2 | 642 | \\breakpoint delete --force 2 |
| 643 | \\ | ||
| 644 | \\breakpoint set --file module.zig --source-pattern-regexp '_ = lc;' | ||
| 645 | \\process continue | ||
| 646 | \\frame variable pc lc | ||
| 647 | \\thread backtrace --count 2 | ||
| 648 | \\breakpoint delete --force 3 | ||
| 649 | \\ | ||
| 650 | \\breakpoint set --file module.zig --line 7 | ||
| 651 | \\process continue | ||
| 652 | \\frame variable pd ld | ||
| 653 | \\thread backtrace --count 2 | ||
| 654 | \\breakpoint delete --force 4 | ||
| 627 | , | 655 | , |
| 628 | &.{ | 656 | &.{ |
| 629 | \\/module.zig:2:5 | 657 | \\(lldb) frame variable pa la |
| 658 | \\(u32) pa = 12 | ||
| 659 | \\(u32) la = 4294967283 | ||
| 660 | \\(lldb) thread backtrace --count 2 | ||
| 661 | \\* thread #1, name = 'inline_call', stop reason = breakpoint 1.1 | ||
| 662 | \\ * frame #0: inline_call`main.fa(pa=12) at main.zig:10:5 | ||
| 663 | \\ frame #1: inline_call`main.main at main.zig:3:7 | ||
| 630 | \\(lldb) breakpoint delete --force 1 | 664 | \\(lldb) breakpoint delete --force 1 |
| 631 | \\1 breakpoints deleted; 0 breakpoint locations disabled. | 665 | \\1 breakpoints deleted; 0 breakpoint locations disabled. |
| 632 | , | 666 | , |
| 633 | \\/module.zig:5:5 | 667 | \\(lldb) frame variable pb lb |
| 668 | \\(u32) pb = 34 | ||
| 669 | \\(u32) lb = 4294967261 | ||
| 670 | \\(lldb) thread backtrace --count 2 | ||
| 671 | \\* thread #1, name = 'inline_call', stop reason = breakpoint 2.1 | ||
| 672 | \\ * frame #0: inline_call`main.main [inlined] fb(pb=34) at main.zig:14:5 | ||
| 673 | \\ frame #1: inline_call`main.main at main.zig:4:7 | ||
| 634 | \\(lldb) breakpoint delete --force 2 | 674 | \\(lldb) breakpoint delete --force 2 |
| 635 | \\1 breakpoints deleted; 0 breakpoint locations disabled. | 675 | \\1 breakpoints deleted; 0 breakpoint locations disabled. |
| 676 | , | ||
| 677 | \\(lldb) frame variable pc lc | ||
| 678 | \\(u32) pc = 56 | ||
| 679 | \\(u32) lc = 4294967239 | ||
| 680 | \\(lldb) thread backtrace --count 2 | ||
| 681 | \\* thread #1, name = 'inline_call', stop reason = breakpoint 3.1 | ||
| 682 | \\ * frame #0: inline_call`module.fc(pc=56) at module.zig:3:5 | ||
| 683 | \\ frame #1: inline_call`main.main at main.zig:5:14 | ||
| 684 | \\(lldb) breakpoint delete --force 3 | ||
| 685 | \\1 breakpoints deleted; 0 breakpoint locations disabled. | ||
| 686 | , | ||
| 687 | \\(lldb) frame variable pd ld | ||
| 688 | \\(u32) pd = 78 | ||
| 689 | \\(u32) ld = 4294967217 | ||
| 690 | \\(lldb) thread backtrace --count 2 | ||
| 691 | \\* thread #1, name = 'inline_call', stop reason = breakpoint 4.1 | ||
| 692 | \\ * frame #0: inline_call`main.main [inlined] fd(pd=78) at module.zig:7:5 | ||
| 693 | \\ frame #1: inline_call`main.main at main.zig:6:14 | ||
| 694 | \\(lldb) breakpoint delete --force 4 | ||
| 695 | \\1 breakpoints deleted; 0 breakpoint locations disabled. | ||
| 636 | }, | 696 | }, |
| 637 | ); | 697 | ); |
| 638 | } | 698 | } |