Auto merge of #89917 - davidtwco:issue-60705-stabilize-rust-symbol-mangling-scheme, r=wesleywiser
sess: default to v0 symbol mangling on nightly cc rust-lang/rust#60705 rust-lang/compiler-team#938 Rust's current mangling scheme depends on compiler internals; loses information about generic parameters (and other things) which makes for a worse experience when using external tools that need to interact with Rust symbol names; is inconsistent; and can contain `.` characters which aren't universally supported. Therefore, Rust has defined its own symbol mangling scheme which is defined in terms of the Rust language, not the compiler implementation; encodes information about generic parameters in a reversible way; has a consistent definition; and generates symbols that only use the characters `A-Z`, `a-z`, `0-9`, and `_`. Support for the new Rust symbol mangling scheme has been added to upstream tools that will need to interact with Rust symbols (e.g. debuggers). This pull request changes the default symbol mangling scheme from the legacy scheme to the new Rust mangling scheme on nightly. The following pull requests implemented v0 mangling in rustc (if I'm missing any, let me know): - rust-lang/rust#57967 - rust-lang/rust#63559 - rust-lang/rust#75675 - rust-lang/rust#77452 - rust-lang/rust#77554 - rust-lang/rust#83767 - rust-lang/rust#87194 - rust-lang/rust#87789 Rust's symbol mangling scheme has support in the following external tools: - `binutils`/`gdb` (GNU `libiberty`) - [[PATCH] Move rust_{is_mangled,demangle_sym} to a private libiberty header. ](https://gcc.gnu.org/pipermail/gcc-patches/2019-June/523011.html) committed as979526c9ce- [[PATCH] Simplify and generalize rust-demangle's unescaping logic. ](https://gcc.gnu.org/pipermail/gcc-patches/2019-August/527835.html) committed as42bf58bb13- [[PATCH] Remove some restrictions from rust-demangle. ](https://gcc.gnu.org/pipermail/gcc-patches/2019-September/530445.html) committed ase1cb00db67- [[PATCH] Refactor rust-demangle to be independent of C++ demangling. ](https://gcc.gnu.org/pipermail/gcc-patches/2019-November/533719.html) ([original submission](https://gcc.gnu.org/pipermail/gcc-patches/2019-October/532388.html)) committed as32fc3719e0- [[PATCH] Support the new ("v0") mangling scheme in rust-demangle. ](https://gcc.gnu.org/pipermail/gcc-patches/2020-November/558905.html) ([original submission](https://gcc.gnu.org/pipermail/gcc-patches/2020-March/542012.html)) committed as84096498a7- `lldb`/`llvm-objdump`/`llvm-nm`/`llvm-symbolizer`/`llvm-cxxfilt`/etc -7310403e3c-c8c2b4629f-0a2d4f3f24- Linux `perf` - `valgrind` - [Update demangler to support Rust v0 name mangling.](https://bugs.kde.org/show_bug.cgi?id=431306) https://github.com/rust-lang/rust/pull/85530#issuecomment-857855379 contains a summary of the most recent crater run of the v0 mangling, and the remaining issues from that were fixed by rust-lang/rust#87194 (confirmed by follow-up crater run, https://github.com/rust-lang/rust/pull/85530#issuecomment-883679416). `@rustbot` label +T-compiler r? `@michaelwoerister`
This commit is contained in:
commit
683dd08db5
20 changed files with 61 additions and 55 deletions
|
|
@ -1530,7 +1530,11 @@ impl Options {
|
|||
}
|
||||
|
||||
pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
|
||||
self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
|
||||
self.cg.symbol_mangling_version.unwrap_or(if self.unstable_features.is_nightly_build() {
|
||||
SymbolManglingVersion::V0
|
||||
} else {
|
||||
SymbolManglingVersion::Legacy
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -47,6 +47,6 @@ foo::example_function
|
|||
## Mangling versions
|
||||
|
||||
`rustc` supports different mangling versions which encode the names in different ways.
|
||||
The legacy version (which is currently the default) is not described here.
|
||||
The legacy version (which is currently the default on beta/stable) is not described here.
|
||||
The "v0" mangling scheme addresses several limitations of the legacy format,
|
||||
and is described in the [v0 Symbol Format](v0.md) chapter.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use std::arch::x86_64::{__m128, _mm_blend_ps};
|
|||
pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128, ret: *mut __m128) {
|
||||
let f = {
|
||||
// check that _mm_blend_ps is not being inlined into the closure
|
||||
// CHECK-LABEL: {{sse41_blend_nofeature.*closure.*:}}
|
||||
// CHECK-LABEL: {{sse41_blend_nofeature:}}
|
||||
// CHECK-NOT: blendps
|
||||
// CHECK: {{call .*_mm_blend_ps.*}}
|
||||
// CHECK-NOT: blendps
|
||||
|
|
@ -29,7 +29,7 @@ pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128, ret: *mut __m128) {
|
|||
pub fn sse41_blend_noinline(x: __m128, y: __m128) -> __m128 {
|
||||
let f = {
|
||||
// check that _mm_blend_ps is being inlined into the closure
|
||||
// CHECK-LABEL: {{sse41_blend_noinline.*closure.*:}}
|
||||
// CHECK-LABEL: {{sse41_blend_noinline:}}
|
||||
// CHECK-NOT: _mm_blend_ps
|
||||
// CHECK: blendps
|
||||
// CHECK-NOT: _mm_blend_ps
|
||||
|
|
@ -45,10 +45,10 @@ pub fn sse41_blend_noinline(x: __m128, y: __m128) -> __m128 {
|
|||
pub fn sse41_blend_doinline(x: __m128, y: __m128) -> __m128 {
|
||||
// check that the closure and _mm_blend_ps are being inlined into the function
|
||||
// CHECK-LABEL: sse41_blend_doinline:
|
||||
// CHECK-NOT: {{sse41_blend_doinline.*closure.*}}
|
||||
// CHECK-NOT: {{sse41_blend_doinline:}}
|
||||
// CHECK-NOT: _mm_blend_ps
|
||||
// CHECK: blendps
|
||||
// CHECK-NOT: {{sse41_blend_doinline.*closure.*}}
|
||||
// CHECK-NOT: {{sse41_blend_doinline.*}}
|
||||
// CHECK-NOT: _mm_blend_ps
|
||||
// CHECK: ret
|
||||
let f = {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
extern crate breakpoint_panic_handler;
|
||||
|
||||
// Verify function name doesn't contain unacceaptable characters.
|
||||
// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN:[a-zA-Z0-9$_]+square[a-zA-Z0-9$_]+]]
|
||||
// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN:[a-zA-Z0-9$_]+square]]
|
||||
|
||||
// CHECK-LABEL: .visible .entry top_kernel(
|
||||
#[no_mangle]
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#[no_mangle]
|
||||
pub fn iota() -> [u8; 16] {
|
||||
// OPT-NOT: core..array..Guard
|
||||
// NORMAL: core..array..Guard
|
||||
// OPT-NOT: core::array::Guard
|
||||
// NORMAL: core::array::Guard
|
||||
std::array::from_fn(|i| i as _)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=3
|
||||
//@ compile-flags: -Copt-level=3 --crate-name=test
|
||||
//@ ignore-std-debug-assertions
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ pub async fn async_block() {
|
|||
f.await;
|
||||
}
|
||||
x(
|
||||
// CHECK-LABEL: ; cold_attribute::async_block::{{{{closure}}}}::{{{{closure}}}}
|
||||
// CHECK-LABEL: ; cold_attribute::async_block::{closure#0}::{closure#0}
|
||||
// CHECK-NEXT: Function Attrs: cold {{.*}}
|
||||
#[cold]
|
||||
async {},
|
||||
|
|
@ -33,7 +33,7 @@ pub fn closure() {
|
|||
f()
|
||||
}
|
||||
x(
|
||||
// CHECK-LABEL: ; cold_attribute::closure::{{{{closure}}}}
|
||||
// CHECK-LABEL: ; cold_attribute::closure::{closure#0}
|
||||
// CHECK-NEXT: Function Attrs: cold {{.*}}
|
||||
#[cold]
|
||||
|| {},
|
||||
|
|
@ -43,14 +43,14 @@ pub fn closure() {
|
|||
pub struct S;
|
||||
|
||||
impl S {
|
||||
// CHECK-LABEL: ; cold_attribute::S::method
|
||||
// CHECK-LABEL: ; <cold_attribute::S>::method
|
||||
// CHECK-NEXT: Function Attrs: cold {{.*}}
|
||||
#[cold]
|
||||
pub fn method(&self) {}
|
||||
}
|
||||
|
||||
pub trait Trait {
|
||||
// CHECK-LABEL: ; cold_attribute::Trait::trait_fn
|
||||
// CHECK-LABEL: ; <cold_attribute::S as cold_attribute::Trait>::trait_fn
|
||||
// CHECK-NEXT: Function Attrs: cold {{.*}}
|
||||
#[cold]
|
||||
fn trait_fn(&self) {}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// The iterator may unroll for values smaller than a certain threshold so we
|
||||
// use a larger value to prevent unrolling.
|
||||
|
||||
//@ compile-flags: -Copt-level=3
|
||||
//@ compile-flags: -Copt-level=3 --crate-name=test
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ fn test(x: u64) {
|
|||
}
|
||||
|
||||
// CHECK: .balign 4
|
||||
// CHECK: add rax, 2
|
||||
// CHECK: add rax, 1
|
||||
// CHECK: add rax, 42
|
||||
|
||||
// CHECK: .balign 4
|
||||
// CHECK: add rax, 1
|
||||
// CHECK: add rax, 2
|
||||
// CHECK: add rax, 42
|
||||
|
||||
#[unsafe(naked)]
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
#[inline(never)]
|
||||
fn test<const SIZE: usize>() {
|
||||
// CHECK-LABEL: no_alloca_inside_if_false::test
|
||||
// CHECK-LABEL: no_alloca_inside_if_false::test::<8192>
|
||||
// CHECK: start:
|
||||
// CHECK-NEXT: alloca [{{12|24}} x i8]
|
||||
// CHECK-NOT: alloca
|
||||
// CHECK-NEXT: = alloca [{{12|24}} x i8]
|
||||
// CHECK-NOT: = alloca
|
||||
if const { SIZE < 4096 } {
|
||||
let arr = [0u8; SIZE];
|
||||
std::hint::black_box(&arr);
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@
|
|||
|
||||
use std::ptr::NonNull;
|
||||
|
||||
// CHECK-LABEL: ; core::ptr::non_null::NonNull<T>::new_unchecked
|
||||
// CHECK-LABEL: ; <core::ptr::non_null::NonNull<u8>>::new_unchecked
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: @nonnull_new
|
||||
#[no_mangle]
|
||||
pub unsafe fn nonnull_new(ptr: *mut u8) -> NonNull<u8> {
|
||||
// CHECK: ; call core::ptr::non_null::NonNull<T>::new_unchecked
|
||||
// CHECK: ; call <core::ptr::non_null::NonNull<u8>>::new_unchecked
|
||||
unsafe { NonNull::new_unchecked(ptr) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK-LABEL: define{{.*}}4core3ptr47drop_in_place$LT$dyn$u20$core..marker..Send$GT$
|
||||
// CHECK-LABEL: define{{.*}}4core3ptr13drop_in_placeDNtNtB4_6marker4Send
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%.+}}, metadata !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE")
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ struct PresentDrop;
|
|||
|
||||
impl Drop for PresentDrop {
|
||||
fn drop(&mut self) {}
|
||||
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}PresentDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place{{.*}}PresentDrop{{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
}
|
||||
|
||||
pub fn foo() {
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ pub fn main() {
|
|||
// `DynCompatible` is indeed dyn-compatible.
|
||||
let _: &dyn DynCompatible = &s;
|
||||
|
||||
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::DynCompatible>::dyn_name{{.*}}reify.shim.fnptr
|
||||
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::DynCompatible>::dyn_name::{shim:reify_fnptr#0}
|
||||
let dyn_name = S::dyn_name as fn(&S) -> &str;
|
||||
let _unused = dyn_name(&s);
|
||||
|
||||
// CHECK: call fn_ptr_reify_shim::DynCompatible::dyn_name_default{{.*}}reify.shim.fnptr
|
||||
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::DynCompatible>::dyn_name_default::{shim:reify_fnptr#0}
|
||||
let dyn_name_default = S::dyn_name_default as fn(&S) -> &str;
|
||||
let _unused = dyn_name_default(&s);
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ pub fn main() {
|
|||
let not_dyn_name = S::not_dyn_name as fn() -> &'static str;
|
||||
let _unused = not_dyn_name();
|
||||
|
||||
// CHECK: call fn_ptr_reify_shim::NotDynCompatible::not_dyn_name_default{{$}}
|
||||
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::NotDynCompatible>::not_dyn_name_default{{$}}
|
||||
let not_dyn_name_default = S::not_dyn_name_default as fn() -> &'static str;
|
||||
let _unused = not_dyn_name_default();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ impl MyTrait for Thing {}
|
|||
// the shim calls the real function
|
||||
// CHECK-LABEL: define
|
||||
// CHECK-SAME: my_naked_function
|
||||
// CHECK-SAME: reify.shim.fnptr
|
||||
// CHECK-SAME: reify_fnptr
|
||||
|
||||
// CHECK-LABEL: main
|
||||
#[unsafe(no_mangle)]
|
||||
|
|
@ -40,7 +40,7 @@ pub fn main() {
|
|||
// main calls the shim function
|
||||
// CHECK: call void
|
||||
// CHECK-SAME: my_naked_function
|
||||
// CHECK-SAME: reify.shim.fnptr
|
||||
// CHECK-SAME: reify_fnptr
|
||||
(F)(&Thing);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ pub trait MyTrait {
|
|||
fn unsanitized(&self, b: &mut u8) -> u8;
|
||||
fn sanitized(&self, b: &mut u8) -> u8;
|
||||
|
||||
// CHECK-LABEL: ; sanitize_off::MyTrait::unsanitized_default
|
||||
// CHECK-LABEL: ; <() as sanitize_off::MyTrait>::unsanitized_default
|
||||
// CHECK-NEXT: ; Function Attrs:
|
||||
// CHECK-NOT: sanitize_address
|
||||
// CHECK: start:
|
||||
|
|
@ -77,7 +77,7 @@ pub trait MyTrait {
|
|||
*b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: ; sanitize_off::MyTrait::sanitized_default
|
||||
// CHECK-LABEL: ; <() as sanitize_off::MyTrait>::sanitized_default
|
||||
// CHECK-NEXT: ; Function Attrs:
|
||||
// CHECK: sanitize_address
|
||||
// CHECK: start:
|
||||
|
|
|
|||
|
|
@ -9,35 +9,35 @@
|
|||
|
||||
// lldb-command:run
|
||||
// lldb-command:v B
|
||||
// lldb-check: ::B::[...] = false
|
||||
// lldb-check: ::B = false
|
||||
// lldb-command:v I
|
||||
// lldb-check: ::I::[...] = -1
|
||||
// lldb-check: ::I = -1
|
||||
// lldb-command:v --format=d C
|
||||
// lldb-check: ::C::[...] = 97
|
||||
// lldb-check: ::C = 97
|
||||
// lldb-command:v --format=d I8
|
||||
// lldb-check: ::I8::[...] = 68
|
||||
// lldb-check: ::I8 = 68
|
||||
// lldb-command:v I16
|
||||
// lldb-check: ::I16::[...] = -16
|
||||
// lldb-check: ::I16 = -16
|
||||
// lldb-command:v I32
|
||||
// lldb-check: ::I32::[...] = -32
|
||||
// lldb-check: ::I32 = -32
|
||||
// lldb-command:v I64
|
||||
// lldb-check: ::I64::[...] = -64
|
||||
// lldb-check: ::I64 = -64
|
||||
// lldb-command:v U
|
||||
// lldb-check: ::U::[...] = 1
|
||||
// lldb-check: ::U = 1
|
||||
// lldb-command:v --format=d U8
|
||||
// lldb-check: ::U8::[...] = 100
|
||||
// lldb-check: ::U8 = 100
|
||||
// lldb-command:v U16
|
||||
// lldb-check: ::U16::[...] = 16
|
||||
// lldb-check: ::U16 = 16
|
||||
// lldb-command:v U32
|
||||
// lldb-check: ::U32::[...] = 32
|
||||
// lldb-check: ::U32 = 32
|
||||
// lldb-command:v U64
|
||||
// lldb-check: ::U64::[...] = 64
|
||||
// lldb-check: ::U64 = 64
|
||||
// lldb-command:v F16
|
||||
// lldb-check: ::F16::[...] = 1.5
|
||||
// lldb-check: ::F16 = 1.5
|
||||
// lldb-command:v F32
|
||||
// lldb-check: ::F32::[...] = 2.5
|
||||
// lldb-check: ::F32 = 2.5
|
||||
// lldb-command:v F64
|
||||
// lldb-check: ::F64::[...] = 3.5
|
||||
// lldb-check: ::F64 = 3.5
|
||||
|
||||
// gdb-command:run
|
||||
// gdb-command:print B
|
||||
|
|
@ -103,4 +103,6 @@ fn main() {
|
|||
let b = unsafe { F16 };
|
||||
}
|
||||
|
||||
fn _zzz() {()}
|
||||
fn _zzz() {
|
||||
()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
// lldb-command:v TEST
|
||||
// lldb-check:(unsigned long) TEST = 3735928559
|
||||
// lldb-command:v OTHER_TEST
|
||||
// lldb-check:(unsigned long) no_mangle_info::namespace::OTHER_TEST::[...] = 42
|
||||
// lldb-check:(unsigned long) no_mangle_info::namespace::OTHER_TEST = 42
|
||||
|
||||
// === CDB TESTS ==================================================================================
|
||||
// cdb-command: g
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ debug!!!
|
|||
stack backtrace:
|
||||
0: std::panicking::begin_panic
|
||||
1: short_ice_remove_middle_frames_2::eight
|
||||
2: short_ice_remove_middle_frames_2::seven::{{closure}}
|
||||
2: short_ice_remove_middle_frames_2::seven::{closure#0}
|
||||
[... omitted 3 frames ...]
|
||||
3: short_ice_remove_middle_frames_2::fifth
|
||||
4: short_ice_remove_middle_frames_2::fourth::{{closure}}
|
||||
4: short_ice_remove_middle_frames_2::fourth::{closure#0}
|
||||
[... omitted 4 frames ...]
|
||||
5: short_ice_remove_middle_frames_2::first
|
||||
6: short_ice_remove_middle_frames_2::main
|
||||
7: core::ops::function::FnOnce::call_once
|
||||
7: <fn() as core::ops::function::FnOnce<()>>::call_once
|
||||
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ stack backtrace:
|
|||
0: std::panicking::begin_panic
|
||||
1: short_ice_remove_middle_frames::seven
|
||||
2: short_ice_remove_middle_frames::sixth
|
||||
3: short_ice_remove_middle_frames::fifth::{{closure}}
|
||||
3: short_ice_remove_middle_frames::fifth::{closure#0}
|
||||
[... omitted 4 frames ...]
|
||||
4: short_ice_remove_middle_frames::second
|
||||
5: short_ice_remove_middle_frames::first::{{closure}}
|
||||
5: short_ice_remove_middle_frames::first::{closure#0}
|
||||
6: short_ice_remove_middle_frames::first
|
||||
7: short_ice_remove_middle_frames::main
|
||||
8: core::ops::function::FnOnce::call_once
|
||||
8: <fn() as core::ops::function::FnOnce<()>>::call_once
|
||||
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
//
|
||||
//@ run-fail
|
||||
//@ error-pattern: Call to blocking function
|
||||
//@ error-pattern: realtime_blocking::blocking::
|
||||
//@ error-pattern: realtime_blocking::blocking
|
||||
//@ ignore-backends: gcc
|
||||
#![feature(sanitize)]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue