diff --git a/build.zig b/build.zig index 6487cc615d..00aed04e80 100644 --- a/build.zig +++ b/build.zig @@ -437,8 +437,8 @@ pub fn build(b: *std.Build) !void { .skip_non_native = skip_non_native, .skip_libc = skip_libc, .use_llvm = use_llvm, - // 2520100864 was observed on an x86_64-linux-gnu host. - .max_rss = 2772110950, + // 2923515904 was observed on an x86_64-linux-gnu host. + .max_rss = 3100000000, })); test_modules_step.dependOn(tests.addModuleTests(b, .{ diff --git a/src/Compilation.zig b/src/Compilation.zig index ba599d0207..13c1e50d9e 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -7225,7 +7225,7 @@ fn buildOutputFromZig( assert(out.* == null); out.* = crt_file; - comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); + comp.queueLinkTaskMode(crt_file.full_object_path, &config); } pub const CrtFileOptions = struct { @@ -7349,7 +7349,7 @@ pub fn build_crt_file( try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node); const crt_file = try sub_compilation.toCrtFile(); - comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); + comp.queueLinkTaskMode(crt_file.full_object_path, &config); { comp.mutex.lock(); @@ -7359,11 +7359,14 @@ pub fn build_crt_file( } } -pub fn queueLinkTaskMode(comp: *Compilation, path: Cache.Path, output_mode: std.builtin.OutputMode) void { - comp.queueLinkTasks(switch (output_mode) { +pub fn queueLinkTaskMode(comp: *Compilation, path: Cache.Path, config: *const Compilation.Config) void { + comp.queueLinkTasks(switch (config.output_mode) { .Exe => unreachable, .Obj => &.{.{ .load_object = path }}, - .Lib => &.{.{ .load_archive = path }}, + .Lib => &.{switch (config.link_mode) { + .static => .{ .load_archive = path }, + .dynamic => .{ .load_dso = path }, + }}, }); } diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index 49b5328a3a..b6d16d57ec 100644 --- a/src/Compilation/Config.zig +++ b/src/Compilation/Config.zig @@ -195,10 +195,7 @@ pub fn resolve(options: Options) ResolveError!Config { // Note that using the LLVM backend does not necessarily mean using LLVM libraries. // For example, Zig can emit .bc and .ll files directly, and this is still considered // using "the LLVM backend". - const use_llvm = b: { - // If we have no zig code to compile, no need for LLVM. - if (!options.have_zcu) break :b false; - + const can_use_llvm = b: { // If emitting to LLVM bitcode object format, must use LLVM backend. if (options.emit_llvm_ir or options.emit_llvm_bc) { if (options.use_llvm == false) @@ -237,6 +234,13 @@ pub fn resolve(options: Options) ResolveError!Config { break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target); }; + const use_llvm = b: { + // If we have no zig code to compile, no need for LLVM. + if (!options.have_zcu) break :b false; + + break :b can_use_llvm; + }; + if (options.emit_bin and options.have_zcu) { if (!use_lib_llvm and use_llvm) { // Explicit request to use LLVM to produce an object file, but without @@ -273,7 +277,7 @@ pub fn resolve(options: Options) ResolveError!Config { } if (options.use_lld) |x| break :b x; - break :b true; + break :b can_use_llvm; }; // Make a decision on whether to use Clang or Aro for translate-c and compiling C files. diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 8ea3928971..92114095bf 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -378,9 +378,9 @@ pub fn emitMir(emit: *Emit) Error!void { }; break :stack_value &loc_buf[0]; } } }, - .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{ .addr = .{ - .sym = mir_inst.data.as.sym_index, - } } }, + .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{ + .addr_reloc = mir_inst.data.as.sym_index, + } }, .pseudo_dbg_local_aso => loc: { const sym_off = emit.lower.mir.extraData( bits.SymbolOffset, @@ -388,7 +388,7 @@ pub fn emitMir(emit: *Emit) Error!void { ).data; break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{ sym: { - loc_buf[0] = .{ .addr = .{ .sym = sym_off.sym_index } }; + loc_buf[0] = .{ .addr_reloc = sym_off.sym_index }; break :sym &loc_buf[0]; }, off: { @@ -437,7 +437,7 @@ pub fn emitMir(emit: *Emit) Error!void { .none => .{ .constu = 0 }, .reg => |reg| .{ .breg = reg.dwarfNum() }, .frame, .table, .rip_inst => unreachable, - .reloc => |sym_index| .{ .addr = .{ .sym = sym_index } }, + .reloc => |sym_index| .{ .addr_reloc = sym_index }, }; break :base &loc_buf[0]; }, diff --git a/src/libs/libcxx.zig b/src/libs/libcxx.zig index 43acb0e93a..17a7d3d29e 100644 --- a/src/libs/libcxx.zig +++ b/src/libs/libcxx.zig @@ -308,7 +308,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! assert(comp.libcxx_static_lib == null); const crt_file = try sub_compilation.toCrtFile(); comp.libcxx_static_lib = crt_file; - comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); + comp.queueLinkTaskMode(crt_file.full_object_path, &config); } pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { @@ -504,7 +504,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr assert(comp.libcxxabi_static_lib == null); const crt_file = try sub_compilation.toCrtFile(); comp.libcxxabi_static_lib = crt_file; - comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); + comp.queueLinkTaskMode(crt_file.full_object_path, &config); } pub fn addCxxArgs( diff --git a/src/libs/libtsan.zig b/src/libs/libtsan.zig index 73c2c49f72..8a5ffd2eab 100644 --- a/src/libs/libtsan.zig +++ b/src/libs/libtsan.zig @@ -325,7 +325,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo }; const crt_file = try sub_compilation.toCrtFile(); - comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); + comp.queueLinkTaskMode(crt_file.full_object_path, &config); assert(comp.tsan_lib == null); comp.tsan_lib = crt_file; } diff --git a/src/libs/libunwind.zig b/src/libs/libunwind.zig index 3c2e14bfc5..945689ebab 100644 --- a/src/libs/libunwind.zig +++ b/src/libs/libunwind.zig @@ -195,7 +195,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr }; const crt_file = try sub_compilation.toCrtFile(); - comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); + comp.queueLinkTaskMode(crt_file.full_object_path, &config); assert(comp.libunwind_static_lib == null); comp.libunwind_static_lib = crt_file; } diff --git a/src/libs/musl.zig b/src/libs/musl.zig index 25f49eb91b..d208b09827 100644 --- a/src/libs/musl.zig +++ b/src/libs/musl.zig @@ -278,7 +278,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro errdefer comp.gpa.free(basename); const crt_file = try sub_compilation.toCrtFile(); - comp.queueLinkTaskMode(crt_file.full_object_path, output_mode); + comp.queueLinkTaskMode(crt_file.full_object_path, &config); { comp.mutex.lock(); defer comp.mutex.unlock(); diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index ca90f016a6..d65646744f 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -785,6 +785,7 @@ const Entry = struct { } const Index = enum(u32) { + //got_proc, _, const Optional = enum(u32) { @@ -1040,7 +1041,7 @@ const Entry = struct { const symbol = zo.symbol(reloc.target_sym); try dwarf.resolveReloc( entry_off + reloc.source_off, - @bitCast(symbol.address(.{}, elf_file) + @as(i64, @intCast(reloc.target_off)) - + @bitCast(symbol.address(.{}, elf_file) + @as(i64, @intCast(@intFromEnum(reloc.target_off))) - if (symbol.flags.is_tls) elf_file.dtpAddress() else 0), @intFromEnum(dwarf.address_size), ); @@ -1051,7 +1052,7 @@ const Entry = struct { const ref = zo.getSymbolRef(reloc.target_sym, macho_file); try dwarf.resolveReloc( entry_off + reloc.source_off, - ref.getSymbol(macho_file).?.getAddress(.{}, macho_file), + ref.getSymbol(macho_file).?.getAddress(.{}, macho_file) + @as(i64, @intCast(@intFromEnum(reloc.target_off))), @intFromEnum(dwarf.address_size), ); } @@ -1080,18 +1081,39 @@ const CrossSectionReloc = struct { const ExternalReloc = struct { source_off: u32 = 0, target_sym: u32, - target_off: u64 = 0, + target_off: enum(u64) { + none = 0, + got = std.math.maxInt(i64) + 1, + _, + + pub fn rel(off: u64) @This() { + const res: @This() = @enumFromInt(off); + switch (res) { + .none => {}, + _ => {}, + .got => unreachable, // assertion failure + } + return res; + } + } = .none, }; pub const Loc = union(enum) { empty, - addr: union(enum) { sym: u32 }, + addr_reloc: u32, + got_reloc: u32, + deref: *const Loc, constu: u64, consts: i64, plus: Bin, reg: u32, breg: u32, push_object_address, + call: struct { + args: []const Loc = &.{}, + unit: Unit.Index, + entry: Entry.Index, + }, form_tls_address: *const Loc, implicit_value: []const u8, stack_value: *const Loc, @@ -1136,11 +1158,17 @@ pub const Loc = union(enum) { const writer = adapter.writer(); switch (loc) { .empty => {}, - .addr => |addr| { + .addr_reloc => |sym_index| { try writer.writeByte(DW.OP.addr); - switch (addr) { - .sym => |sym_index| try adapter.addrSym(sym_index), - } + try adapter.addrSym(sym_index); + }, + .deref => |addr| { + try addr.write(adapter); + try writer.writeByte(DW.OP.deref); + }, + .got_reloc => |sym_index| { + try writer.writeByte(DW.OP.const4s); + try adapter.gotSym(sym_index); }, .constu => |constu| if (std.math.cast(u5, constu)) |lit| { try writer.writeByte(@as(u8, DW.OP.lit0) + lit); @@ -1225,6 +1253,11 @@ pub const Loc = union(enum) { try sleb128(writer, 0); }, .push_object_address => try writer.writeByte(DW.OP.push_object_address), + .call => |call| { + for (call.args) |arg| try arg.write(adapter); + try writer.writeByte(DW.OP.call_ref); + try adapter.infoEntry(call.unit, call.entry); + }, .form_tls_address => |addr| { try addr.write(adapter); try writer.writeByte(DW.OP.form_tls_address); @@ -1385,12 +1418,12 @@ pub const Cfa = union(enum) { }, .def_cfa_expression => |expr| { try writer.writeByte(DW.CFA.def_cfa_expression); - try wip_nav.frameExprloc(expr); + try wip_nav.frameExprLoc(expr); }, .expression => |reg_expr| { try writer.writeByte(DW.CFA.expression); try uleb128(writer, reg_expr.reg); - try wip_nav.frameExprloc(reg_expr.expr); + try wip_nav.frameExprLoc(reg_expr.expr); }, .val_offset => |reg_off| { const factored_off = @divExact(reg_off.off, wip_nav.dwarf.debug_frame.header.data_alignment_factor); @@ -1407,7 +1440,7 @@ pub const Cfa = union(enum) { .val_expression => |reg_expr| { try writer.writeByte(DW.CFA.val_expression); try uleb128(writer, reg_expr.reg); - try wip_nav.frameExprloc(reg_expr.expr); + try wip_nav.frameExprLoc(reg_expr.expr); }, .escape => |bytes| try writer.writeAll(bytes), } @@ -1471,7 +1504,7 @@ pub const WipNav = struct { }); try wip_nav.strp(name); try wip_nav.refType(ty); - try wip_nav.infoExprloc(loc); + try wip_nav.infoExprLoc(loc); wip_nav.any_children = true; } @@ -1733,6 +1766,9 @@ pub const WipNav = struct { fn endian(_: ExprLocCounter) std.builtin.Endian { return @import("builtin").cpu.arch.endian(); } + fn gotSym(counter: *ExprLocCounter, _: u32) error{}!void { + counter.stream.bytes_written += 4; + } fn addrSym(counter: *ExprLocCounter, _: u32) error{}!void { counter.stream.bytes_written += @intFromEnum(counter.address_size); } @@ -1741,7 +1777,7 @@ pub const WipNav = struct { } }; - fn infoExprloc(wip_nav: *WipNav, loc: Loc) UpdateError!void { + fn infoExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void { var counter: ExprLocCounter = .init(wip_nav.dwarf); try loc.write(&counter); @@ -1753,6 +1789,14 @@ pub const WipNav = struct { fn endian(ctx: @This()) std.builtin.Endian { return ctx.wip_nav.dwarf.endian; } + fn gotSym(ctx: @This(), sym_index: u32) UpdateError!void { + try ctx.wip_nav.infoExternalReloc(.{ + .source_off = @intCast(ctx.wip_nav.debug_info.items.len), + .target_sym = sym_index, + .target_off = .got, + }); + try ctx.wip_nav.debug_info.appendNTimes(ctx.wip_nav.dwarf.gpa, 0, 4); + } fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void { try ctx.wip_nav.infoAddrSym(sym_index, 0); } @@ -1768,12 +1812,12 @@ pub const WipNav = struct { try wip_nav.infoExternalReloc(.{ .source_off = @intCast(wip_nav.debug_info.items.len), .target_sym = sym_index, - .target_off = sym_off, + .target_off = .rel(sym_off), }); try wip_nav.debug_info.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size)); } - fn frameExprloc(wip_nav: *WipNav, loc: Loc) UpdateError!void { + fn frameExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void { var counter: ExprLocCounter = .init(wip_nav.dwarf); try loc.write(&counter); @@ -1785,6 +1829,14 @@ pub const WipNav = struct { fn endian(ctx: @This()) std.builtin.Endian { return ctx.wip_nav.dwarf.endian; } + fn gotSym(ctx: @This(), sym_index: u32) UpdateError!void { + try ctx.wip_nav.frameExternalReloc(.{ + .source_off = @intCast(ctx.wip_nav.debug_frame.items.len), + .target_sym = sym_index, + .target_off = .got, + }); + try ctx.wip_nav.debug_frame.appendNTimes(ctx.wip_nav.dwarf.gpa, 0, 4); + } fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void { try ctx.wip_nav.frameAddrSym(sym_index, 0); } @@ -1800,7 +1852,7 @@ pub const WipNav = struct { try wip_nav.frameExternalReloc(.{ .source_off = @intCast(wip_nav.debug_frame.items.len), .target_sym = sym_index, - .target_off = sym_off, + .target_off = .rel(sym_off), }); try wip_nav.debug_frame.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size)); } @@ -2286,50 +2338,81 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) !Unit.Index { const mod_gop = try dwarf.mods.getOrPut(dwarf.gpa, mod); const unit: Unit.Index = @enumFromInt(mod_gop.index); if (!mod_gop.found_existing) { - errdefer _ = dwarf.mods.pop(); - mod_gop.value_ptr.* = .{ - .root_dir_path = undefined, - .dirs = .empty, - .files = .empty, - }; - errdefer mod_gop.value_ptr.dirs.deinit(dwarf.gpa); - try mod_gop.value_ptr.dirs.putNoClobber(dwarf.gpa, unit, {}); - assert(try dwarf.debug_aranges.section.addUnit( - DebugAranges.headerBytes(dwarf), - DebugAranges.trailerBytes(dwarf), - dwarf, - ) == unit); - errdefer dwarf.debug_aranges.section.popUnit(dwarf.gpa); - assert(try dwarf.debug_frame.section.addUnit( - DebugFrame.headerBytes(dwarf), - DebugFrame.trailerBytes(dwarf), - dwarf, - ) == unit); - errdefer dwarf.debug_frame.section.popUnit(dwarf.gpa); - assert(try dwarf.debug_info.section.addUnit( - DebugInfo.headerBytes(dwarf), - DebugInfo.trailer_bytes, - dwarf, - ) == unit); - errdefer dwarf.debug_info.section.popUnit(dwarf.gpa); - assert(try dwarf.debug_line.section.addUnit( - DebugLine.headerBytes(dwarf, 5, 25), - DebugLine.trailer_bytes, - dwarf, - ) == unit); - errdefer dwarf.debug_line.section.popUnit(dwarf.gpa); - assert(try dwarf.debug_loclists.section.addUnit( - DebugLocLists.headerBytes(dwarf), - DebugLocLists.trailer_bytes, - dwarf, - ) == unit); - errdefer dwarf.debug_loclists.section.popUnit(dwarf.gpa); - assert(try dwarf.debug_rnglists.section.addUnit( - DebugRngLists.headerBytes(dwarf), - DebugRngLists.trailer_bytes, - dwarf, - ) == unit); - errdefer dwarf.debug_rnglists.section.popUnit(dwarf.gpa); + { + errdefer _ = dwarf.mods.pop(); + mod_gop.value_ptr.* = .{ + .root_dir_path = undefined, + .dirs = .empty, + .files = .empty, + }; + errdefer mod_gop.value_ptr.dirs.deinit(dwarf.gpa); + try mod_gop.value_ptr.dirs.putNoClobber(dwarf.gpa, unit, {}); + assert(try dwarf.debug_aranges.section.addUnit( + DebugAranges.headerBytes(dwarf), + DebugAranges.trailerBytes(dwarf), + dwarf, + ) == unit); + errdefer dwarf.debug_aranges.section.popUnit(dwarf.gpa); + assert(try dwarf.debug_frame.section.addUnit( + DebugFrame.headerBytes(dwarf), + DebugFrame.trailerBytes(dwarf), + dwarf, + ) == unit); + errdefer dwarf.debug_frame.section.popUnit(dwarf.gpa); + assert(try dwarf.debug_info.section.addUnit( + DebugInfo.headerBytes(dwarf), + DebugInfo.trailer_bytes, + dwarf, + ) == unit); + errdefer dwarf.debug_info.section.popUnit(dwarf.gpa); + assert(try dwarf.debug_line.section.addUnit( + DebugLine.headerBytes(dwarf, 5, 25), + DebugLine.trailer_bytes, + dwarf, + ) == unit); + errdefer dwarf.debug_line.section.popUnit(dwarf.gpa); + assert(try dwarf.debug_loclists.section.addUnit( + DebugLocLists.headerBytes(dwarf), + DebugLocLists.trailer_bytes, + dwarf, + ) == unit); + errdefer dwarf.debug_loclists.section.popUnit(dwarf.gpa); + assert(try dwarf.debug_rnglists.section.addUnit( + DebugRngLists.headerBytes(dwarf), + DebugRngLists.trailer_bytes, + dwarf, + ) == unit); + errdefer dwarf.debug_rnglists.section.popUnit(dwarf.gpa); + } + //if (dwarf.bin_file.cast(.elf)) |elf_file| { + // if (unit == .main) assert(try dwarf.addCommonEntry(unit) == .got_proc); + // if (mod.pic and dwarf.debug_info.section.getUnit(.main).getEntry(.got_proc).len == 0) { + // var wip_nav: WipNav = .{ + // .dwarf = dwarf, + // .pt = undefined, + // .unit = .main, + // .entry = .got_proc, + // .any_children = false, + // .func = .none, + // .func_sym_index = undefined, + // .func_high_pc = undefined, + // .blocks = undefined, + // .cfi = undefined, + // .debug_frame = .empty, + // .debug_info = .empty, + // .debug_line = .empty, + // .debug_loclists = .empty, + // .pending_lazy = .empty, + // }; + // defer wip_nav.deinit(); + // try wip_nav.abbrevCode(.proc); + // try wip_nav.infoExprLoc(.{ .deref = &.{ .plus = .{ + // &.empty, + // &.{ .addr_reloc = try elf_file.zigObjectPtr().?.getGlobalSymbol(elf_file, "_GLOBAL_OFFSET_TABLE_", null) }, + // } } }); + // try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items); + // } + //} } return unit; } @@ -2384,7 +2467,8 @@ fn initWipNavInner( else => {}, } - const unit = try dwarf.getUnit(file.mod.?); + const mod = file.mod.?; + const unit = try dwarf.getUnit(mod); const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop(); if (nav_gop.found_existing) { @@ -2425,13 +2509,22 @@ fn initWipNavInner( }, &nav, inst_info.file, &decl); try wip_nav.strp(nav.fqn.toSlice(ip)); const ty: Type = nav_val.typeOf(zcu); - const addr: Loc = .{ .addr = .{ .sym = sym_index } }; - const loc: Loc = if (decl.is_threadlocal) .{ .form_tls_address = &addr } else addr; + const addr: Loc = .{ .addr_reloc = sym_index }; + const loc: Loc = loc: { + if (dwarf.bin_file.cast(.elf)) |elf_file| if (decl.linkage == .@"extern" and mod.pic) + // TODO: lldb doesn't support call :( + //.{ .call = .{ .args = &.{.{ .got_reloc = sym_index }}, .unit = .main, .entry = .got_proc } } + break :loc .{ .deref = &.{ .plus = .{ + &.{ .addr_reloc = try elf_file.zigObjectPtr().?.getGlobalSymbol(elf_file, "_GLOBAL_OFFSET_TABLE_", null) }, + &.{ .got_reloc = sym_index }, + } } }; + break :loc if (decl.is_threadlocal) .{ .form_tls_address = &addr } else addr; + }; switch (decl.kind) { .unnamed_test, .@"test", .decltest, .@"comptime", .@"usingnamespace" => unreachable, .@"const" => { const const_ty_reloc_index = try wip_nav.refForward(); - try wip_nav.infoExprloc(loc); + try wip_nav.infoExprLoc(loc); try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse ty.abiAlignment(zcu).toByteUnits().?); try diw.writeByte(@intFromBool(decl.linkage != .normal)); @@ -2441,7 +2534,7 @@ fn initWipNavInner( }, .@"var" => { try wip_nav.refType(ty); - try wip_nav.infoExprloc(loc); + try wip_nav.infoExprLoc(loc); try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse ty.abiAlignment(zcu).toByteUnits().?); try diw.writeByte(@intFromBool(decl.linkage != .normal)); @@ -2649,7 +2742,7 @@ pub fn finishWipNavFunc( .{ .source_off = 1 + @intFromEnum(dwarf.address_size), .target_sym = wip_nav.func_sym_index, - .target_off = code_size, + .target_off = .rel(code_size), }, }); try dwarf.debug_rnglists.section.replaceEntry( @@ -3838,7 +3931,7 @@ fn updateLazyValue( byte_offset += base_ptr.byte_offset; }; try wip_nav.abbrevCode(.location_comptime_value); - try wip_nav.infoExprloc(.{ .implicit_pointer = .{ + try wip_nav.infoExprLoc(.{ .implicit_pointer = .{ .unit = base_unit, .entry = base_entry, .offset = byte_offset, @@ -4360,7 +4453,7 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A assert(abbrev_code != .null); const entry: Entry.Index = @enumFromInt(@intFromEnum(abbrev_code)); if (dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).getEntry(entry).len > 0) return @intFromEnum(abbrev_code); - var debug_abbrev = std.ArrayList(u8).init(dwarf.gpa); + var debug_abbrev: std.ArrayList(u8) = .init(dwarf.gpa); defer debug_abbrev.deinit(); const daw = debug_abbrev.writer(); const abbrev = AbbrevCode.abbrevs.get(abbrev_code); @@ -4422,7 +4515,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path); } - var header = std.ArrayList(u8).init(dwarf.gpa); + var header: std.ArrayList(u8) = .init(dwarf.gpa); defer header.deinit(); if (dwarf.debug_aranges.section.dirty) { for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| { @@ -4888,6 +4981,7 @@ const AbbrevCode = enum { comptime_value_field_comptime_state, comptime_value_elem_runtime_bits, comptime_value_elem_comptime_state, + //proc, const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_instance_func_generic)); comptime { @@ -5757,6 +5851,12 @@ const AbbrevCode = enum { .{ .ZIG_comptime_value, .ref_addr }, }, }, + //.proc = .{ + // .tag = .dwarf_procedure, + // .attrs = &.{ + // .{ .location, .exprloc }, + // }, + //}, .null = undefined, }); }; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index af7167095a..d1b1512828 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -463,8 +463,11 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void { for (entry.external_relocs.items) |reloc| { const target_sym = self.symbol(reloc.target_sym); const r_offset = entry_off + reloc.source_off; - const r_addend: i64 = @intCast(reloc.target_off); - const r_type = relocation.dwarf.externalRelocType(target_sym.*, sect_index, dwarf.address_size, cpu_arch); + const r_addend: i64 = switch (reloc.target_off) { + .none, .got => 0, + else => |off| @intCast(@intFromEnum(off)), + }; + const r_type = relocation.dwarf.externalRelocType(target_sym.*, reloc.target_off == .got, sect_index, dwarf.address_size, cpu_arch); atom_ptr.addRelocAssumeCapacity(.{ .r_offset = r_offset, .r_addend = r_addend, @@ -947,7 +950,7 @@ pub fn getNavVAddr( .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ .source_off = @intCast(reloc_info.offset), .target_sym = this_sym_index, - .target_off = reloc_info.addend, + .target_off = .rel(reloc_info.addend), }), .plan9 => unreachable, .none => unreachable, @@ -980,7 +983,7 @@ pub fn getUavVAddr( .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ .source_off = @intCast(reloc_info.offset), .target_sym = sym_index, - .target_off = reloc_info.addend, + .target_off = .rel(reloc_info.addend), }), .plan9 => unreachable, .none => unreachable, diff --git a/src/link/Elf/relocation.zig b/src/link/Elf/relocation.zig index 047312cd68..9af4453948 100644 --- a/src/link/Elf/relocation.zig +++ b/src/link/Elf/relocation.zig @@ -108,12 +108,13 @@ pub const dwarf = struct { pub fn externalRelocType( target: Symbol, + is_got: bool, source_section: Dwarf.Section.Index, address_size: Dwarf.AddressSize, cpu_arch: std.Target.Cpu.Arch, ) u32 { return switch (cpu_arch) { - .x86_64 => @intFromEnum(@as(elf.R_X86_64, switch (source_section) { + .x86_64 => @intFromEnum(@as(elf.R_X86_64, if (is_got) .GOT32 else switch (source_section) { else => switch (address_size) { .@"32" => if (target.flags.is_tls) .DTPOFF32 else .@"32", .@"64" => if (target.flags.is_tls) .DTPOFF64 else .@"64", diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index a0de866544..aebfe6275f 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -648,7 +648,7 @@ pub fn getNavVAddr( .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ .source_off = @intCast(reloc_info.offset), .target_sym = sym_index, - .target_off = reloc_info.addend, + .target_off = .rel(reloc_info.addend), }), .plan9 => unreachable, .none => unreachable, @@ -688,7 +688,7 @@ pub fn getUavVAddr( .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ .source_off = @intCast(reloc_info.offset), .target_sym = sym_index, - .target_off = reloc_info.addend, + .target_off = .rel(reloc_info.addend), }), .plan9 => unreachable, .none => unreachable, diff --git a/src/target.zig b/src/target.zig index bd12ca9e70..247b783439 100644 --- a/src/target.zig +++ b/src/target.zig @@ -223,6 +223,10 @@ pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool { /// than or equal to the number of behavior tests as the respective LLVM backend. pub fn selfHostedBackendIsAsRobustAsLlvm(target: std.Target) bool { if (target.cpu.arch.isSpirV()) return true; + if (target.cpu.arch == .x86_64 and target.ptrBitWidth() == 64) return switch (target.ofmt) { + .elf, .macho => true, + else => false, + }; return false; } diff --git a/test/behavior/math.zig b/test/behavior/math.zig index d77603f537..d6d169b0cc 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -1722,6 +1722,7 @@ test "signed zeros are represented properly" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; const S = struct { fn doTheTest() !void { diff --git a/test/tests.zig b/test/tests.zig index 810ed02bc1..c45e3ef561 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -1113,8 +1113,6 @@ const test_targets = blk: { .os_tag = .linux, .abi = .none, }, - .use_llvm = false, - .use_lld = false, }, .{ .target = .{ @@ -1123,8 +1121,6 @@ const test_targets = blk: { .os_tag = .linux, .abi = .none, }, - .use_llvm = false, - .use_lld = false, .pic = true, }, .{ @@ -1134,8 +1130,6 @@ const test_targets = blk: { .os_tag = .linux, .abi = .none, }, - .use_llvm = false, - .use_lld = false, .strip = true, }, .{ @@ -1144,6 +1138,8 @@ const test_targets = blk: { .os_tag = .linux, .abi = .none, }, + .use_llvm = true, + .use_lld = true, }, .{ .target = .{