Skip to content

Commit

Permalink
Expose an option for producing 64-bit DWARF format
Browse files Browse the repository at this point in the history
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 ziglang#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.
  • Loading branch information
David Gonzalez Martin committed Apr 8, 2023
1 parent 66520c8 commit 2789829
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 4 deletions.
9 changes: 9 additions & 0 deletions lib/std/Build/CompileStep.zig
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ disable_stack_probing: bool,
disable_sanitize_c: bool,
sanitize_thread: bool,
rdynamic: bool,
dwarf_format: ?std.builtin.DwarfFormat = null,
import_memory: bool = false,
/// For WebAssembly targets, this will allow for undefined symbols to
/// be imported from the host environment.
Expand Down Expand Up @@ -1478,6 +1479,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 => {},
Expand Down
7 changes: 7 additions & 0 deletions lib/std/builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,13 @@ pub const WasiExecModel = enum {
reactor,
};

/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const DwarfFormat = enum {
dwarf32,
dwarf64,
};

/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const Version = struct {
Expand Down
2 changes: 2 additions & 0 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,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.builtin.DwarfFormat = 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.
Expand Down Expand Up @@ -1513,6 +1514,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,
Expand Down
9 changes: 8 additions & 1 deletion src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,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;
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/llvm/bindings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,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;
Expand Down
2 changes: 2 additions & 0 deletions src/link.zig
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ pub const Options = struct {
compatibility_version: ?std.builtin.Version,
libc_installation: ?*const LibCInstallation,

dwarf_format: ?std.builtin.DwarfFormat = null,

/// WASI-only. Type of WASI execution model ("command" or "reactor").
wasi_exec_model: std.builtin.WasiExecModel = undefined,

Expand Down
6 changes: 6 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ fn buildOutputType(
var reference_trace: ?u32 = null;
var error_tracing: ?bool = null;
var pdb_out_path: ?[]const u8 = null;
var dwarf_format: ?std.builtin.DwarfFormat = 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
Expand Down Expand Up @@ -1356,6 +1357,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")) {
Expand Down Expand Up @@ -3141,6 +3146,7 @@ fn buildOutputType(
.test_runner_path = test_runner_path,
.disable_lld_caching = !have_enable_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,
Expand Down
6 changes: 5 additions & 1 deletion src/zig_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1168,9 +1168,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) {
Expand Down
2 changes: 1 addition & 1 deletion src/zig_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,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);
Expand Down

0 comments on commit 2789829

Please sign in to comment.