From 48646c6c429b1fff5d274cc19224631b437031c9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 25 Nov 2017 11:10:40 -0800 Subject: [PATCH] Demangle ThinLTO-generated symbols as well --- src/lib.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index eb873bd..3a8e905 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,7 +80,25 @@ pub struct Demangle<'a> { // Note that this demangler isn't quite as fancy as it could be. We have lots // of other information in our symbols like hashes, version, type information, // etc. Additionally, this doesn't handle glue symbols at all. -pub fn demangle(s: &str) -> Demangle { +pub fn demangle(mut s: &str) -> Demangle { + // During ThinLTO LLVM may import and rename internal symbols, so strip out + // those endings first as they're on of the last manglings applied to symbol + // names. + let llvm = ".llvm."; + if let Some(i) = s.find(llvm) { + let candidate = &s[i + llvm.len()..]; + let all_hex = candidate.chars().all(|c| { + match c { + 'A' ... 'F' | '0' ... '9' => true, + _ => false, + } + }); + + if all_hex { + s = &s[..i]; + } + } + // First validate the symbol. If it doesn't look like anything we're // expecting, we just print it literally. Note that we must handle non-rust // symbols because we could have any function in the backtrace. @@ -358,4 +376,11 @@ mod tests { // Not a valid hash, has a non-hex-digit. t_nohash!("_ZN3foo17hg5af221e174051e9E", "foo::hg5af221e174051e9"); } + + #[test] + fn demangle_thinlto() { + // One element, no hash. + t!("_ZN3fooE.llvm.9D1C9369", "foo"); + t_nohash!("_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9", "backtrace::foo"); + } }