use once_cell::sync::Lazy;
use regex::Regex;
use std::env::consts::ARCH;
use std::result;
use symbolic::common::{Arch, Name};
use symbolic::demangle::DemangleOptions;
pub type Result<T> = result::Result<T, anyhow::Error>;
pub fn demangle_options() -> DemangleOptions {
DemangleOptions::complete().return_type(false)
}
pub fn get_compile_time_arch() -> &'static str {
use Arch::*;
match ARCH {
"x86" => X86,
"x86_64" => Amd64,
"arm" => Arm,
"aarch64" => Arm64,
"mips" => Mips,
"mips64" => Mips64,
"powerpc" => Ppc,
"powerpc64" => Ppc64,
_ => Unknown,
}
.name()
}
pub(crate) fn normalize_anonymous_namespace(text: &str) -> String {
let fixed = text.replace("`anonymous namespace'", "(anonymous namespace)");
String::from(&fixed)
}
pub(crate) fn fix_symbol_name<'a>(name: &'a Name<'a>) -> Name<'a> {
static COMPILER_NNN: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r"((\.(cold|constprop|llvm|localalias|lto_priv|isra|part|str)(\.[0-9]+)?)|( ?\[clone[^\]]*\] ?))+$",
)
.unwrap()
});
let fixed = COMPILER_NNN.replace(name.as_str(), "");
let fixed = normalize_anonymous_namespace(&fixed);
Name::new(fixed, name.mangling(), name.language())
}
#[cfg(test)]
mod tests {
use super::*;
use symbolic::common::{Language, NameMangling};
#[test]
fn test_fix_symbol_name() {
let name = Name::new("hello", NameMangling::Mangled, Language::Unknown);
assert_eq!(name, fix_symbol_name(&name));
let test_names = [
"hello.llvm.1234567890",
"hello.str.158.llvm.1786438672924483777",
"hello [clone .constprop.0] [clone .isra.0] [clone .cold]",
"hello.localalias",
"hello.constprop.0.isra.0",
];
for test_name in test_names {
let test_name = Name::new(test_name, NameMangling::Mangled, Language::Unknown);
assert_eq!(name, fix_symbol_name(&test_name));
}
let test_name = Name::new(
"hello [clone foo][bar]",
NameMangling::Mangled,
Language::Unknown,
);
assert_eq!("hello [clone foo][bar]", fix_symbol_name(&test_name));
}
#[test]
fn test_normalize_anonymous_namespace() {
let name = "(anonymous namespace)";
assert_eq!("(anonymous namespace)", normalize_anonymous_namespace(name));
let name = "`anonymous namespace'";
assert_eq!("(anonymous namespace)", normalize_anonymous_namespace(name));
}
}