Skip to content

Commit

Permalink
Demangle function names recovered from DWARF
Browse files Browse the repository at this point in the history
  • Loading branch information
negasora committed Jun 21, 2024
1 parent aa9c28e commit 38e719b
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
3 changes: 3 additions & 0 deletions docs/about/open-source.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ The previous tools are used in the generation of our documentation, but are not
- [clang-sys] ([clang-sys license] - APACHE 2.0)
- [core-foundation-sys] ([core-foundation-sys license] - APACHE 2.0 / MIT)
- [core-foundation] ([core-foundation license] - APACHE 2.0 / MIT)
- [cpp-demangle] ([cpp-demangle license] - APACHE 2.0 / MIT)
- [cpufeatures] ([cpufeatures license] - APACHE 2.0 / MIT)
- [crc] ([crc license] - APACHE 2.0 / MIT)
- [crc-catalog] ([crc-catalog license] - APACHE 2.0 / MIT)
Expand Down Expand Up @@ -426,6 +427,8 @@ Please note that we offer no support for running Binary Ninja with modified Qt l
[core-foundation-sys license]: https://github.com/servo/core-foundation-rs/blob/master/LICENSE-MIT
[core-foundation]: https://github.com/servo/core-foundation-rs
[core-foundation license]: https://github.com/servo/core-foundation-rs/blob/master/LICENSE-MIT
[cpp-demangle]: https://github.com/gimli-rs/cpp_demangle
[cpp-demangle license]: https://github.com/gimli-rs/cpp_demangle/blob/master/LICENSE-MIT
[cpufeatures]: https://github.com/RustCrypto/utils/tree/master/cpufeatures
[cpufeatures license]: https://github.com/RustCrypto/utils/blob/master/cpufeatures/LICENSE-MIT
[crc]: https://github.com/mrhooray/crc-rs
Expand Down
11 changes: 11 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rust/examples/dwarf/dwarf_import/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ binaryninja = { path = "../../../" }
gimli = "0.28"
log = "0.4.20"
iset = "0.2.2"
cpp_demangle = "0.4.3"
regex = "1"
38 changes: 37 additions & 1 deletion rust/examples/dwarf/dwarf_import/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::OnceLock;

use crate::dwarfdebuginfo::{DebugInfoBuilder, DebugInfoBuilderContext, TypeUID};
use crate::helpers::*;
use crate::types::get_type;

use binaryninja::templatesimplifier::simplify_str_to_str;
use cpp_demangle::DemangleOptions;
use gimli::{constants, DebuggingInformationEntry, Reader, Unit};
use regex::Regex;

fn get_parameters<R: Reader<Offset = usize>>(
unit: &Unit<R>,
Expand Down Expand Up @@ -69,11 +74,42 @@ pub(crate) fn parse_function_entry<R: Reader<Offset = usize>>(
debug_info_builder: &mut DebugInfoBuilder,
) -> Option<usize> {
// Collect function properties (if they exist in this DIE)
let full_name = debug_info_builder_context.get_name(unit, entry);
let raw_name = get_raw_name(unit, entry, debug_info_builder_context);
let return_type = get_type(unit, entry, debug_info_builder_context, debug_info_builder);
let address = get_start_address(unit, entry, debug_info_builder_context);
let (parameters, variable_arguments) = get_parameters(unit, entry, debug_info_builder_context, debug_info_builder);

// If we have a raw name, it might be mangled, see if we can demangle it into full_name
// raw_name should contain a superset of the info we have in full_name
let mut full_name = None;
if let Some(possibly_mangled_name) = &raw_name {
if possibly_mangled_name.starts_with('_') {
static OPTIONS_MEM: OnceLock<DemangleOptions> = OnceLock::new();
let demangle_options = OPTIONS_MEM.get_or_init(|| {
DemangleOptions::new()
.no_return_type()
.hide_expression_literal_types()
.no_params()
});

static ABI_REGEX_MEM: OnceLock<Regex> = OnceLock::new();
let abi_regex = ABI_REGEX_MEM.get_or_init(|| {
Regex::new(r"\[abi:v\d+\]").unwrap()
});
if let Ok(sym) = cpp_demangle::Symbol::new(possibly_mangled_name) {
if let Ok(demangled) = sym.demangle(demangle_options) {
let cleaned = abi_regex.replace_all(&demangled, "");
let simplified = simplify_str_to_str(&cleaned);
full_name = Some(simplified.to_string());
}
}
}
}

// If we didn't demangle the raw name, fetch the name given
if full_name.is_none() {
full_name = debug_info_builder_context.get_name(unit, entry)
}

debug_info_builder.insert_function(full_name, raw_name, return_type, address, &parameters, variable_arguments)
}

0 comments on commit 38e719b

Please sign in to comment.