From d026202a26e56e7e2ea20ca49509fdcf8b937020 Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Thu, 6 Apr 2023 10:16:20 +0200 Subject: [PATCH] Expose an option for producing 64-bit DWARF format This commit enables producing 64-bit DWARF format for Zig executables that are produced through the LLVM backend. This is achieved by exposing both command-line flags and CompileStep flags. The production of the 64-bit format only affects binaries that use the DWARF format and it is disabled on MacOS due to it being problematic. This commit, despite generating the interface for the Zig user to be able to tell the compile which format is wanted, is just implemented for the LLVM backend, so clang and the self-hosted backends will need this to be implemented in a future commit. This is an effort to work around #7962, since the emission of the 64-bit format automatically produces 64-bit relocations. Further investigation will be needed to make DWARF 32-bit format to emit bigger relocations when needed and not make the linker angry. --- lib/std/Build/CompileStep.zig | 9 +++++++++ lib/std/dwarf.zig | 5 +++++ src/Compilation.zig | 2 ++ src/codegen/llvm.zig | 9 ++++++++- src/codegen/llvm/bindings.zig | 2 +- src/link.zig | 2 ++ src/main.zig | 6 ++++++ src/zig_llvm.cpp | 6 +++++- src/zig_llvm.h | 2 +- 9 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/std/Build/CompileStep.zig b/lib/std/Build/CompileStep.zig index 9340ec8d99ffc9cab281b45bf9855cd94d62886d..2c51d5885250cdf0654b0fe944d361e5ddeadbb6 100644 --- a/lib/std/Build/CompileStep.zig +++ b/lib/std/Build/CompileStep.zig @@ -69,6 +69,7 @@ disable_stack_probing: bool, disable_sanitize_c: bool, sanitize_thread: bool, rdynamic: bool, +dwarf_format: ?std.dwarf.Format = null, import_memory: bool = false, /// For WebAssembly targets, this will allow for undefined symbols to /// be imported from the host environment. @@ -1449,6 +1450,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try addFlag(&zig_args, "strip", self.strip); try addFlag(&zig_args, "unwind-tables", self.unwind_tables); + if (!self.producesPdbFile()) { + if (self.dwarf_format) |dwarf_format| { + try zig_args.append(switch (dwarf_format) { + .dwarf32 => "-gdwarf32", + .dwarf64 => "-gdwarf64", + }); + } + } switch (self.compress_debug_sections) { .none => {}, diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index 99dff14c3615c906383a754ded3e2ad5966245e7..505a5cb886ce74aea15890609bdf484112e5da1f 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -147,6 +147,11 @@ pub const CC = enum(u8) { GNU_borland_fastcall_i386 = 0x41, }; +pub const Format = enum { + dwarf32, + dwarf64, +}; + const PcRange = struct { start: u64, end: u64, diff --git a/src/Compilation.zig b/src/Compilation.zig index 48a0412b2395ead63c4c9888ebd6c36bbef2fdf5..848b1594fa193ba644378f25f875998c0d56f1b6 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -620,6 +620,7 @@ pub const InitOptions = struct { test_name_prefix: ?[]const u8 = null, test_runner_path: ?[]const u8 = null, subsystem: ?std.Target.SubSystem = null, + dwarf_format: ?std.dwarf.Format = null, /// WASI-only. Type of WASI execution model ("command" or "reactor"). wasi_exec_model: ?std.builtin.WasiExecModel = null, /// (Zig compiler development) Enable dumping linker's state as JSON. @@ -1517,6 +1518,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .disable_lld_caching = options.disable_lld_caching or cache_mode == .whole, .subsystem = options.subsystem, .is_test = options.is_test, + .dwarf_format = options.dwarf_format, .wasi_exec_model = wasi_exec_model, .hash_style = options.hash_style, .enable_link_snapshots = options.enable_link_snapshots, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 47b47cc80744ba4b8dfdf6f642a6009392c97128..23d9af39e06db364f3a203b47f21447f2115d246 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -433,7 +433,14 @@ pub const Object = struct { if (!options.strip) { switch (options.target.ofmt) { .coff => llvm_module.addModuleCodeViewFlag(), - else => llvm_module.addModuleDebugInfoFlag(), + else => { + const dwarf_format = options.dwarf_format orelse .dwarf32; + const produce_dwarf64 = switch (dwarf_format) { + .dwarf32 => false, + .dwarf64 => true, + }; + llvm_module.addModuleDebugInfoFlag(produce_dwarf64); + }, } const di_builder = llvm_module.createDIBuilder(true); opt_di_builder = di_builder; diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 63cac80db8853a481b066a493d5a36e429696ff4..55f0ba896355ea78b9eb29744efce95253a24030 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -409,7 +409,7 @@ pub const Module = opaque { extern fn LLVMSetTarget(M: *Module, Triple: [*:0]const u8) void; pub const addModuleDebugInfoFlag = ZigLLVMAddModuleDebugInfoFlag; - extern fn ZigLLVMAddModuleDebugInfoFlag(module: *Module) void; + extern fn ZigLLVMAddModuleDebugInfoFlag(module: *Module, dwarf64: bool) void; pub const addModuleCodeViewFlag = ZigLLVMAddModuleCodeViewFlag; extern fn ZigLLVMAddModuleCodeViewFlag(module: *Module) void; diff --git a/src/link.zig b/src/link.zig index c8999cee4764cd5ed73f3c1bd861695cec56c9d7..a0a1bdad949e067ca6ea9c151a5785f5e9593d56 100644 --- a/src/link.zig +++ b/src/link.zig @@ -200,6 +200,8 @@ pub const Options = struct { compatibility_version: ?std.builtin.Version, libc_installation: ?*const LibCInstallation, + dwarf_format: ?std.dwarf.Format = null, + /// WASI-only. Type of WASI execution model ("command" or "reactor"). wasi_exec_model: std.builtin.WasiExecModel = undefined, diff --git a/src/main.zig b/src/main.zig index 2bc4961cba939aaa4fb4bbb0663455a258f7fa56..81a83d580d80dbb43b875f2725513b042c0b57e0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -844,6 +844,7 @@ fn buildOutputType( var reference_trace: ?u32 = null; var error_tracing: ?bool = null; var pdb_out_path: ?[]const u8 = null; + var dwarf_format: ?std.dwarf.Format = null; // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. // This array is populated by zig cc frontend and then has to be converted to zig-style @@ -1355,6 +1356,10 @@ fn buildOutputType( strip = true; } else if (mem.eql(u8, arg, "-fno-strip")) { strip = false; + } else if (mem.eql(u8, arg, "-gdwarf32")) { + dwarf_format = .dwarf32; + } else if (mem.eql(u8, arg, "-gdwarf64")) { + dwarf_format = .dwarf64; } else if (mem.eql(u8, arg, "-fformatted-panics")) { formatted_panics = true; } else if (mem.eql(u8, arg, "-fno-formatted-panics")) { @@ -3145,6 +3150,7 @@ fn buildOutputType( .test_runner_path = test_runner_path, .disable_lld_caching = !output_to_cache, .subsystem = subsystem, + .dwarf_format = dwarf_format, .wasi_exec_model = wasi_exec_model, .debug_compile_errors = debug_compile_errors, .enable_link_snapshots = enable_link_snapshots, diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index a88442042203a9cd6fba78afae392b69d76e9387..af53bd1d27a2b8870b730be767730465fee055e3 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -1163,9 +1163,13 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, free(native_triple); } -void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) { +void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module, bool produce_dwarf64) { unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION); unwrap(module)->addModuleFlag(Module::Warning, "Dwarf Version", 4); + + if (produce_dwarf64) { + unwrap(module)->addModuleFlag(Module::Warning, "DWARF64", 1); + } } void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) { diff --git a/src/zig_llvm.h b/src/zig_llvm.h index e466be9e8c27f7179b0f5f1ca76ca6b1d93a00d1..8f24d045a2b8b62564051b54d0834d5098159ad8 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -238,7 +238,7 @@ ZIG_EXTERN_C unsigned ZigLLVMTag_DW_union_type(void); ZIG_EXTERN_C struct ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved); ZIG_EXTERN_C void ZigLLVMDisposeDIBuilder(struct ZigLLVMDIBuilder *dbuilder); -ZIG_EXTERN_C void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module); +ZIG_EXTERN_C void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module, bool produce_dwarf64); ZIG_EXTERN_C void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module); ZIG_EXTERN_C void ZigLLVMSetModulePICLevel(LLVMModuleRef module); ZIG_EXTERN_C void ZigLLVMSetModulePIELevel(LLVMModuleRef module); -- 2.54.0