Skip to content

Commit

Permalink
Add demangle utility (resolve: #1054)
Browse files Browse the repository at this point in the history
  • Loading branch information
romainthomas committed Aug 17, 2024
1 parent f864b71 commit 7c3b4a3
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 1 deletion.
1 change: 1 addition & 0 deletions api/python/lief/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ class range_t:
def size(self) -> int: ...

def current_platform() -> lief.PLATFORMS: ...
def demangle(mangled: str) -> Optional[str]: ...
def disable_leak_warning() -> None: ...
@overload
def hash(arg: lief.Object, /) -> int: ...
Expand Down
17 changes: 16 additions & 1 deletion api/python/src/pyLIEF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>

#include "LIEF/utils.hpp"
#include "LIEF/hash.hpp"
#include "LIEF/Object.hpp"
#include "LIEF/range.hpp"
Expand Down Expand Up @@ -208,7 +209,21 @@ void init(nb::module_& m) {
- leaked function "export_symbol"
- ... skipped remainder
nanobind: this is likely caused by a reference counting issue in the binding code.
)doc");
)doc"_doc);

m.def("demangle",
[] (const std::string& mangled) {
return LIEF::py::value_or_none(&LIEF::demangle, mangled);
},
R"doc(
Demangle the given input.
.. warnings::
This function only works with the extended version of LIEF
)doc"_doc,
"mangled"_a
);

LIEF::py::init_extension(m);

Expand Down
1 change: 1 addition & 0 deletions api/rust/autocxx_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ include_cpp! {
name!(autocxx_ffi)

generate!("is_extended")
generate!("demangle")

generate_pod!("Span")
block_constructors!("Span")
Expand Down
11 changes: 11 additions & 0 deletions api/rust/cargo/lief/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,14 @@ pub use debug_location::DebugLocation;
pub fn is_extended() -> bool {
lief_ffi::is_extended()
}

/// Try to demangle the given input.
///
/// This function requires the extended version of LIEF
pub fn demangle(mangled: &str) -> Result<String, Error> {
to_conv_result!(
lief_ffi::demangle,
*mangled,
|e: cxx::UniquePtr<cxx::String>| { e.to_string() }
);
}
6 changes: 6 additions & 0 deletions api/rust/include/LIEF/rust/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
*/
#pragma once
#include "LIEF/utils.hpp"
#include "LIEF/rust/error.hpp"

inline bool is_extended() {
return LIEF::is_extended();
}

inline std::string demangle(std::string mangled, uint32_t& err) {
return details::make_error<std::string>(LIEF::demangle(mangled), err);
}

7 changes: 7 additions & 0 deletions doc/sphinx/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ Changelog

* Add support for RISC-V architecture


:Extended:

* Add :func:`lief.demangle` / :cpp:func:`LIEF::demangle` to demangle symbols
(c.f. :issue:`1054`)


0.15.1 - July 23th, 2024
------------------------

Expand Down
5 changes: 5 additions & 0 deletions include/LIEF/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ LIEF_API result<std::u16string> u8tou16(const std::string& string);

//! Whether this version of LIEF includes extended features
LIEF_API bool is_extended();

//! Demangle the given input.
//!
//! This function only works with the extended version of LIEF
LIEF_API result<std::string> demangle(const std::string& mangled);
}


Expand Down
6 changes: 6 additions & 0 deletions src/messages.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,11 @@
"Please checkout " LIEF_DOC_PREFIX "/latest/extended/intro.html for the details"
#endif

#if !defined(NEEDS_EXTENDED_MSG)
#define NEEDS_EXTENDED_MSG \
"This function requires the extended version of LIEF.\n" \
"Please checkout " LIEF_DOC_PREFIX "/latest/extended/intro.html for the details"
#endif


#endif
9 changes: 9 additions & 0 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "third-party/utfcpp.hpp"

#include "LIEF/config.h"
#include "logging.hpp"
#include "messages.hpp"

namespace LIEF {

Expand Down Expand Up @@ -90,5 +92,12 @@ bool is_extended() {
return lief_extended;
}

#if !defined(LIEF_EXTENDED)
result<std::string> demangle(const std::string&/*mangled*/) {
LIEF_WARN(NEEDS_EXTENDED_MSG);
return make_error_code(lief_errors::not_implemented);
}
#endif


} // namespace LIEF
14 changes: 14 additions & 0 deletions tests/api/test_demangle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import lief
import pytest

if not lief.__extended__:
pytest.skip("skipping: extended version only", allow_module_level=True)

def test_itanium():
assert lief.demangle("_ZN8nanobind6detail16type_caster_baseIN4LIEF3DEX6HeaderEEcvRS4_Ev") == "nanobind::detail::type_caster_base<LIEF::DEX::Header>::operator LIEF::DEX::Header&()"

def test_rust():
assert lief.demangle("_RNvCskwGfYPst2Cb_3foo16example_function") == "foo::example_function"

def test_ms():
assert lief.demangle("??_C@_0CC@KGNKJKHE@heap_failure_listentry_corruptio@FNODOBFM@") == '"heap_failure_listentry_corruptio"...'

0 comments on commit 7c3b4a3

Please sign in to comment.