Skip to content

Commit 226e181

Browse files
committed
Auto merge of #88550 - dpaoliello:dpaoliello/allocdebuginfo, r=estebank
Include debug info for the allocator shim Issue Details: In some cases it is necessary to generate an "allocator shim" to forward various Rust allocation functions (e.g., `__rust_alloc`) to an underlying function (e.g., `malloc`). However, since this allocator shim is a manually created LLVM module it is not processed via the normal module processing code and so no debug info is generated for it (if debugging info is enabled). Fix Details: * Modify the `debuginfo` code to allow creating debug info for a module without a `CodegenCx` (since it is difficult, and expensive, to create one just to emit some debug info). * After creating the allocator shim add in basic debug info.
2 parents 72a51c3 + 77a96ed commit 226e181

File tree

5 files changed

+66
-41
lines changed

5 files changed

+66
-41
lines changed

Diff for: compiler/rustc_codegen_llvm/src/allocator.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@ use libc::c_uint;
33
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
44
use rustc_middle::bug;
55
use rustc_middle::ty::TyCtxt;
6+
use rustc_session::config::DebugInfo;
67
use rustc_span::symbol::sym;
78

9+
use crate::debuginfo;
810
use crate::llvm::{self, False, True};
911
use crate::ModuleLlvm;
1012

1113
pub(crate) unsafe fn codegen(
1214
tcx: TyCtxt<'_>,
13-
mods: &mut ModuleLlvm,
15+
module_llvm: &mut ModuleLlvm,
16+
module_name: &str,
1417
kind: AllocatorKind,
1518
has_alloc_error_handler: bool,
1619
) {
17-
let llcx = &*mods.llcx;
18-
let llmod = mods.llmod();
20+
let llcx = &*module_llvm.llcx;
21+
let llmod = module_llvm.llmod();
1922
let usize = match tcx.sess.target.pointer_width {
2023
16 => llvm::LLVMInt16TypeInContext(llcx),
2124
32 => llvm::LLVMInt32TypeInContext(llcx),
@@ -132,4 +135,10 @@ pub(crate) unsafe fn codegen(
132135
llvm::LLVMSetTailCall(ret, True);
133136
llvm::LLVMBuildRetVoid(llbuilder);
134137
llvm::LLVMDisposeBuilder(llbuilder);
138+
139+
if tcx.sess.opts.debuginfo != DebugInfo::None {
140+
let dbg_cx = debuginfo::CrateDebugContext::new(llmod);
141+
debuginfo::metadata::compile_unit_metadata(tcx, module_name, &dbg_cx);
142+
dbg_cx.finalize(tcx.sess);
143+
}
135144
}

Diff for: compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+40-32
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_middle::ty::layout::HasTyCtxt;
2929
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
3030
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeFoldable};
3131
use rustc_session::config::{self, DebugInfo};
32+
use rustc_session::Session;
3233
use rustc_span::symbol::Symbol;
3334
use rustc_span::{self, BytePos, Pos, SourceFile, SourceFileAndLine, Span};
3435
use rustc_target::abi::{LayoutOf, Primitive, Size};
@@ -95,45 +96,52 @@ impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> {
9596
composite_types_completed: Default::default(),
9697
}
9798
}
98-
}
99-
100-
/// Creates any deferred debug metadata nodes
101-
pub fn finalize(cx: &CodegenCx<'_, '_>) {
102-
if cx.dbg_cx.is_none() {
103-
return;
104-
}
10599

106-
debug!("finalize");
100+
pub fn finalize(&self, sess: &Session) {
101+
unsafe {
102+
llvm::LLVMRustDIBuilderFinalize(self.builder);
103+
104+
// Debuginfo generation in LLVM by default uses a higher
105+
// version of dwarf than macOS currently understands. We can
106+
// instruct LLVM to emit an older version of dwarf, however,
107+
// for macOS to understand. For more info see #11352
108+
// This can be overridden using --llvm-opts -dwarf-version,N.
109+
// Android has the same issue (#22398)
110+
if let Some(version) = sess.target.dwarf_version {
111+
llvm::LLVMRustAddModuleFlag(self.llmod, "Dwarf Version\0".as_ptr().cast(), version)
112+
}
107113

108-
if gdb::needs_gdb_debug_scripts_section(cx) {
109-
// Add a .debug_gdb_scripts section to this compile-unit. This will
110-
// cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
111-
// which activates the Rust pretty printers for binary this section is
112-
// contained in.
113-
gdb::get_or_insert_gdb_debug_scripts_section_global(cx);
114-
}
114+
// Indicate that we want CodeView debug information on MSVC
115+
if sess.target.is_like_msvc {
116+
llvm::LLVMRustAddModuleFlag(self.llmod, "CodeView\0".as_ptr().cast(), 1)
117+
}
115118

116-
unsafe {
117-
llvm::LLVMRustDIBuilderFinalize(DIB(cx));
118-
// Debuginfo generation in LLVM by default uses a higher
119-
// version of dwarf than macOS currently understands. We can
120-
// instruct LLVM to emit an older version of dwarf, however,
121-
// for macOS to understand. For more info see #11352
122-
// This can be overridden using --llvm-opts -dwarf-version,N.
123-
// Android has the same issue (#22398)
124-
if let Some(version) = cx.sess().target.dwarf_version {
125-
llvm::LLVMRustAddModuleFlag(cx.llmod, "Dwarf Version\0".as_ptr().cast(), version)
119+
// Prevent bitcode readers from deleting the debug info.
120+
let ptr = "Debug Info Version\0".as_ptr();
121+
llvm::LLVMRustAddModuleFlag(
122+
self.llmod,
123+
ptr.cast(),
124+
llvm::LLVMRustDebugMetadataVersion(),
125+
);
126126
}
127+
}
128+
}
127129

128-
// Indicate that we want CodeView debug information on MSVC
129-
if cx.sess().target.is_like_msvc {
130-
llvm::LLVMRustAddModuleFlag(cx.llmod, "CodeView\0".as_ptr().cast(), 1)
130+
/// Creates any deferred debug metadata nodes
131+
pub fn finalize(cx: &CodegenCx<'_, '_>) {
132+
if let Some(dbg_cx) = &cx.dbg_cx {
133+
debug!("finalize");
134+
135+
if gdb::needs_gdb_debug_scripts_section(cx) {
136+
// Add a .debug_gdb_scripts section to this compile-unit. This will
137+
// cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
138+
// which activates the Rust pretty printers for binary this section is
139+
// contained in.
140+
gdb::get_or_insert_gdb_debug_scripts_section_global(cx);
131141
}
132142

133-
// Prevent bitcode readers from deleting the debug info.
134-
let ptr = "Debug Info Version\0".as_ptr();
135-
llvm::LLVMRustAddModuleFlag(cx.llmod, ptr.cast(), llvm::LLVMRustDebugMetadataVersion());
136-
};
143+
dbg_cx.finalize(cx.sess());
144+
}
137145
}
138146

139147
impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {

Diff for: compiler/rustc_codegen_llvm/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,12 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
9292
fn codegen_allocator<'tcx>(
9393
&self,
9494
tcx: TyCtxt<'tcx>,
95-
mods: &mut ModuleLlvm,
95+
module_llvm: &mut ModuleLlvm,
96+
module_name: &str,
9697
kind: AllocatorKind,
9798
has_alloc_error_handler: bool,
9899
) {
99-
unsafe { allocator::codegen(tcx, mods, kind, has_alloc_error_handler) }
100+
unsafe { allocator::codegen(tcx, module_llvm, module_name, kind, has_alloc_error_handler) }
100101
}
101102
fn compile_codegen_unit(
102103
&self,

Diff for: compiler/rustc_codegen_ssa/src/base.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -538,12 +538,18 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
538538
} else if let Some(kind) = tcx.allocator_kind(()) {
539539
let llmod_id =
540540
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
541-
let mut modules = backend.new_metadata(tcx, &llmod_id);
541+
let mut module_llvm = backend.new_metadata(tcx, &llmod_id);
542542
tcx.sess.time("write_allocator_module", || {
543-
backend.codegen_allocator(tcx, &mut modules, kind, tcx.lang_items().oom().is_some())
543+
backend.codegen_allocator(
544+
tcx,
545+
&mut module_llvm,
546+
&llmod_id,
547+
kind,
548+
tcx.lang_items().oom().is_some(),
549+
)
544550
});
545551

546-
Some(ModuleCodegen { name: llmod_id, module_llvm: modules, kind: ModuleKind::Allocator })
552+
Some(ModuleCodegen { name: llmod_id, module_llvm, kind: ModuleKind::Allocator })
547553
} else {
548554
None
549555
};

Diff for: compiler/rustc_codegen_ssa/src/traits/backend.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
120120
fn codegen_allocator<'tcx>(
121121
&self,
122122
tcx: TyCtxt<'tcx>,
123-
mods: &mut Self::Module,
123+
module_llvm: &mut Self::Module,
124+
module_name: &str,
124125
kind: AllocatorKind,
125126
has_alloc_error_handler: bool,
126127
);

0 commit comments

Comments
 (0)