Skip to content

Commit 92ac019

Browse files
authored
Unrolled build for rust-lang#135115
Rollup merge of rust-lang#135115 - Zalathar:dwarf-const, r=workingjubilee cg_llvm: Use constants for DWARF opcodes, instead of FFI calls Split off from rust-lang#134009 to incorporate feedback from rust-lang#134009 (comment). Most of the constant values now come from gimli, which is already a compiler dependency. I noticed that `DW_OP_LLVM_fragment` is an LLVM detail that is not defined by DWARF and could hypothetically change, so I added a static assertion on the C++ side to detect that if it ever happens. r? workingjubilee
2 parents feb32c6 + f50721e commit 92ac019

File tree

8 files changed

+64
-48
lines changed

8 files changed

+64
-48
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3499,6 +3499,7 @@ name = "rustc_codegen_llvm"
34993499
version = "0.0.0"
35003500
dependencies = [
35013501
"bitflags",
3502+
"gimli 0.30.0",
35023503
"itertools",
35033504
"libc",
35043505
"measureme",

Diff for: compiler/rustc_codegen_llvm/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ test = false
99
[dependencies]
1010
# tidy-alphabetical-start
1111
bitflags = "2.4.1"
12+
gimli = "0.30"
1213
itertools = "0.12"
1314
libc = "0.2"
1415
measureme = "11"
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//! Definitions of various DWARF-related constants.
2+
3+
use libc::c_uint;
4+
5+
/// Helper macro to let us redeclare gimli's constants as our own constants
6+
/// with a different type, with less risk of copy-paste errors.
7+
macro_rules! declare_constant {
8+
(
9+
$name:ident : $type:ty
10+
) => {
11+
#[allow(non_upper_case_globals)]
12+
pub(crate) const $name: $type = ::gimli::constants::$name.0 as $type;
13+
14+
// Assert that as-cast probably hasn't changed the value.
15+
const _: () = assert!($name as i128 == ::gimli::constants::$name.0 as i128);
16+
};
17+
}
18+
19+
declare_constant!(DW_TAG_const_type: c_uint);
20+
21+
// DWARF languages.
22+
declare_constant!(DW_LANG_Rust: c_uint);
23+
24+
// DWARF attribute type encodings.
25+
declare_constant!(DW_ATE_boolean: c_uint);
26+
declare_constant!(DW_ATE_float: c_uint);
27+
declare_constant!(DW_ATE_signed: c_uint);
28+
declare_constant!(DW_ATE_unsigned: c_uint);
29+
declare_constant!(DW_ATE_UTF: c_uint);
30+
31+
// DWARF expression operators.
32+
declare_constant!(DW_OP_deref: u64);
33+
declare_constant!(DW_OP_plus_uconst: u64);
34+
/// Defined by LLVM in `llvm/include/llvm/BinaryFormat/Dwarf.h`.
35+
/// Double-checked by a static assertion in `RustWrapper.cpp`.
36+
#[allow(non_upper_case_globals)]
37+
pub(crate) const DW_OP_LLVM_fragment: u64 = 0x1000;

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

+6-21
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_target::spec::DebuginfoKind;
2222
use smallvec::smallvec;
2323
use tracing::{debug, instrument};
2424

25+
pub(crate) use self::type_map::TypeMap;
2526
use self::type_map::{DINodeCreationResult, Stub, UniqueTypeId};
2627
use super::CodegenUnitDebugContext;
2728
use super::namespace::mangled_name_of_instance;
@@ -30,6 +31,7 @@ use super::utils::{
3031
DIB, create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit,
3132
};
3233
use crate::common::{AsCCharPtr, CodegenCx};
34+
use crate::debuginfo::dwarf_const;
3335
use crate::debuginfo::metadata::type_map::build_type_with_children;
3436
use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind};
3537
use crate::llvm::debuginfo::{
@@ -59,23 +61,6 @@ impl fmt::Debug for llvm::Metadata {
5961
}
6062
}
6163

62-
// From DWARF 5.
63-
// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1.
64-
const DW_LANG_RUST: c_uint = 0x1c;
65-
#[allow(non_upper_case_globals)]
66-
const DW_ATE_boolean: c_uint = 0x02;
67-
#[allow(non_upper_case_globals)]
68-
const DW_ATE_float: c_uint = 0x04;
69-
#[allow(non_upper_case_globals)]
70-
const DW_ATE_signed: c_uint = 0x05;
71-
#[allow(non_upper_case_globals)]
72-
const DW_ATE_unsigned: c_uint = 0x07;
73-
#[allow(non_upper_case_globals)]
74-
const DW_ATE_UTF: c_uint = 0x10;
75-
76-
#[allow(non_upper_case_globals)]
77-
const DW_TAG_const_type: c_uint = 0x26;
78-
7964
pub(super) const UNKNOWN_LINE_NUMBER: c_uint = 0;
8065
pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
8166

@@ -90,8 +75,6 @@ type SmallVec<T> = smallvec::SmallVec<[T; 16]>;
9075
mod enums;
9176
mod type_map;
9277

93-
pub(crate) use type_map::TypeMap;
94-
9578
/// Returns from the enclosing function if the type debuginfo node with the given
9679
/// unique ID can be found in the type map.
9780
macro_rules! return_if_di_node_created_in_meantime {
@@ -522,7 +505,7 @@ fn recursion_marker_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> &'ll D
522505
name.as_c_char_ptr(),
523506
name.len(),
524507
cx.tcx.data_layout.pointer_size.bits(),
525-
DW_ATE_unsigned,
508+
dwarf_const::DW_ATE_unsigned,
526509
)
527510
}
528511
})
@@ -781,6 +764,8 @@ fn build_basic_type_di_node<'ll, 'tcx>(
781764
// .natvis visualizers (and perhaps other existing native debuggers?)
782765
let cpp_like_debuginfo = cpp_like_debuginfo(cx.tcx);
783766

767+
use dwarf_const::{DW_ATE_UTF, DW_ATE_boolean, DW_ATE_float, DW_ATE_signed, DW_ATE_unsigned};
768+
784769
let (name, encoding) = match t.kind() {
785770
ty::Never => ("!", DW_ATE_unsigned),
786771
ty::Tuple(elements) if elements.is_empty() => {
@@ -961,7 +946,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
961946

962947
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
963948
debug_context.builder,
964-
DW_LANG_RUST,
949+
dwarf_const::DW_LANG_Rust,
965950
compile_unit_file,
966951
producer.as_c_char_ptr(),
967952
producer.len(),

Diff for: compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty};
1212
use smallvec::smallvec;
1313

1414
use crate::common::{AsCCharPtr, CodegenCx};
15+
use crate::debuginfo::dwarf_const::DW_TAG_const_type;
1516
use crate::debuginfo::metadata::enums::DiscrResult;
1617
use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId};
1718
use crate::debuginfo::metadata::{
18-
DINodeCreationResult, DW_TAG_const_type, NO_GENERICS, NO_SCOPE_METADATA, SmallVec,
19-
UNKNOWN_LINE_NUMBER, build_field_di_node, file_metadata, file_metadata_from_def_id,
20-
size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags,
19+
DINodeCreationResult, NO_GENERICS, NO_SCOPE_METADATA, SmallVec, UNKNOWN_LINE_NUMBER,
20+
build_field_di_node, file_metadata, file_metadata_from_def_id, size_and_align_of, type_di_node,
21+
unknown_file_metadata, visibility_di_flags,
2122
};
2223
use crate::debuginfo::utils::DIB;
2324
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType};

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

+11-9
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::llvm::debuginfo::{
3939
use crate::value::Value;
4040

4141
mod create_scope_map;
42+
mod dwarf_const;
4243
mod gdb;
4344
pub(crate) mod metadata;
4445
mod namespace;
@@ -47,6 +48,10 @@ mod utils;
4748
use self::create_scope_map::compute_mir_scopes;
4849
pub(crate) use self::metadata::build_global_var_di_node;
4950

51+
// FIXME(Zalathar): These `DW_TAG_*` constants are fake values that were
52+
// removed from LLVM in 2015, and are only used by our own `RustWrapper.cpp`
53+
// to decide which C++ API to call. Instead, we should just have two separate
54+
// FFI functions and choose the correct one on the Rust side.
5055
#[allow(non_upper_case_globals)]
5156
const DW_TAG_auto_variable: c_uint = 0x100;
5257
#[allow(non_upper_case_globals)]
@@ -152,29 +157,26 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
152157
indirect_offsets: &[Size],
153158
fragment: Option<Range<Size>>,
154159
) {
160+
use dwarf_const::{DW_OP_LLVM_fragment, DW_OP_deref, DW_OP_plus_uconst};
161+
155162
// Convert the direct and indirect offsets and fragment byte range to address ops.
156-
// FIXME(eddyb) use `const`s instead of getting the values via FFI,
157-
// the values should match the ones in the DWARF standard anyway.
158-
let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() };
159-
let op_plus_uconst = || unsafe { llvm::LLVMRustDIBuilderCreateOpPlusUconst() };
160-
let op_llvm_fragment = || unsafe { llvm::LLVMRustDIBuilderCreateOpLLVMFragment() };
161163
let mut addr_ops = SmallVec::<[u64; 8]>::new();
162164

163165
if direct_offset.bytes() > 0 {
164-
addr_ops.push(op_plus_uconst());
166+
addr_ops.push(DW_OP_plus_uconst);
165167
addr_ops.push(direct_offset.bytes() as u64);
166168
}
167169
for &offset in indirect_offsets {
168-
addr_ops.push(op_deref());
170+
addr_ops.push(DW_OP_deref);
169171
if offset.bytes() > 0 {
170-
addr_ops.push(op_plus_uconst());
172+
addr_ops.push(DW_OP_plus_uconst);
171173
addr_ops.push(offset.bytes() as u64);
172174
}
173175
}
174176
if let Some(fragment) = fragment {
175177
// `DW_OP_LLVM_fragment` takes as arguments the fragment's
176178
// offset and size, both of them in bits.
177-
addr_ops.push(op_llvm_fragment());
179+
addr_ops.push(DW_OP_LLVM_fragment);
178180
addr_ops.push(fragment.start.bits() as u64);
179181
addr_ops.push((fragment.end - fragment.start).bits() as u64);
180182
}

Diff for: compiler/rustc_codegen_llvm/src/llvm/ffi.rs

-3
Original file line numberDiff line numberDiff line change
@@ -2177,9 +2177,6 @@ unsafe extern "C" {
21772177
Location: &'a DILocation,
21782178
BD: c_uint,
21792179
) -> Option<&'a DILocation>;
2180-
pub fn LLVMRustDIBuilderCreateOpDeref() -> u64;
2181-
pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> u64;
2182-
pub fn LLVMRustDIBuilderCreateOpLLVMFragment() -> u64;
21832180

21842181
pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString);
21852182
pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);

Diff for: compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+4-12
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ using namespace llvm;
5454
using namespace llvm::sys;
5555
using namespace llvm::object;
5656

57+
// This opcode is an LLVM detail that could hypothetically change (?), so
58+
// verify that the hard-coded value in `dwarf_const.rs` still agrees with LLVM.
59+
static_assert(dwarf::DW_OP_LLVM_fragment == 0x1000);
60+
5761
// LLVMAtomicOrdering is already an enum - don't create another
5862
// one.
5963
static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
@@ -1397,18 +1401,6 @@ LLVMRustDILocationCloneWithBaseDiscriminator(LLVMMetadataRef Location,
13971401
return wrap(NewLoc.has_value() ? NewLoc.value() : nullptr);
13981402
}
13991403

1400-
extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
1401-
return dwarf::DW_OP_deref;
1402-
}
1403-
1404-
extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1405-
return dwarf::DW_OP_plus_uconst;
1406-
}
1407-
1408-
extern "C" uint64_t LLVMRustDIBuilderCreateOpLLVMFragment() {
1409-
return dwarf::DW_OP_LLVM_fragment;
1410-
}
1411-
14121404
extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
14131405
auto OS = RawRustStringOstream(Str);
14141406
unwrap<llvm::Type>(Ty)->print(OS);

0 commit comments

Comments
 (0)