Skip to content

Commit f121af5

Browse files
committed
Add API to get symbol by name (abstract layer)
API Changes (Python/C++): LIEF::Binary::has_symbol LIEF::Binary::get_symbol It works for ELF, PE, MachO
1 parent ae92f99 commit f121af5

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

Diff for: api/python/Abstract/objects/pyBinary.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ using setter_t = void (Binary::*)(T);
3030
template<class T>
3131
using it_t = T (Binary::*)(void);
3232

33+
template<class T, class P>
34+
using no_const_func = T (Binary::*)(P);
35+
3336
void init_LIEF_Binary_class(py::module& m) {
3437
py::class_<Binary>(m, "Binary")
3538

@@ -80,6 +83,17 @@ void init_LIEF_Binary_class(py::module& m) {
8083
"Return a list in **read only** of binary's abstract " RST_CLASS_REF(lief.Symbol) "",
8184
py::return_value_policy::reference_internal)
8285

86+
.def("has_symbol",
87+
&Binary::has_symbol,
88+
"Check if a " RST_CLASS_REF(lief.Symbol) " with the given name exists",
89+
"symbol_name"_a)
90+
91+
.def("get_symbol",
92+
static_cast<no_const_func<Symbol&, const std::string&>>(&Binary::get_symbol),
93+
"Return the " RST_CLASS_REF(lief.Symbol) " with the given ``name``",
94+
"symbol_name"_a,
95+
py::return_value_policy::reference)
96+
8397
.def("get_function_address",
8498
&Binary::get_function_address,
8599
"Return the address of the given function name",

Diff for: include/LIEF/Abstract/Binary.hpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,19 @@ class DLL_PUBLIC Binary : public Visitable {
4848
Header get_header(void) const;
4949

5050
//! @brief Return list of symbols whose elements **can** be modified
51-
it_symbols get_symbols(void);
51+
it_symbols get_symbols(void);
5252

5353
//! @brief Return list of symbols whose elements **can't** be modified
5454
it_const_symbols get_symbols(void) const;
5555

56+
//! @brief Check if a Symbol with the given name exists
57+
bool has_symbol(const std::string& name) const;
58+
59+
//! @brief Return the Symbol with the given name
60+
const Symbol& get_symbol(const std::string& name) const;
61+
62+
Symbol& get_symbol(const std::string& name);
63+
5664
//! @brief Returns binary's sections
5765
it_sections get_sections(void);
5866
it_const_sections get_sections(void) const;
@@ -82,6 +90,8 @@ class DLL_PUBLIC Binary : public Visitable {
8290
virtual void accept(Visitor& visitor) const override;
8391

8492

93+
94+
8595
//! @brief Patch the content at virtual address @p address with @p patch_value
8696
//!
8797
//! @param[in] address Address to patch

Diff for: src/Abstract/Binary.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,40 @@ it_const_symbols Binary::get_symbols(void) const {
5858
return it_const_symbols{const_cast<Binary*>(this)->get_abstract_symbols()};
5959
}
6060

61+
62+
bool Binary::has_symbol(const std::string& name) const {
63+
symbols_t symbols = const_cast<Binary*>(this)->get_abstract_symbols();
64+
auto&& it_symbol = std::find_if(
65+
std::begin(symbols),
66+
std::end(symbols),
67+
[&name] (const Symbol* s) {
68+
return s->name() == name;
69+
});
70+
71+
return it_symbol != std::end(symbols);
72+
}
73+
74+
const Symbol& Binary::get_symbol(const std::string& name) const {
75+
if (not this->has_symbol(name)) {
76+
throw not_found("Symbol '" + name + "' not found!");
77+
}
78+
79+
symbols_t symbols = const_cast<Binary*>(this)->get_abstract_symbols();
80+
81+
auto&& it_symbol = std::find_if(
82+
std::begin(symbols),
83+
std::end(symbols),
84+
[&name] (const Symbol* s) {
85+
return s->name() == name;
86+
});
87+
88+
return **it_symbol;
89+
}
90+
91+
Symbol& Binary::get_symbol(const std::string& name) {
92+
return const_cast<Symbol&>(static_cast<const Binary*>(this)->get_symbol(name));
93+
}
94+
6195
it_sections Binary::get_sections(void) {
6296
return it_sections{this->get_abstract_sections()};
6397
}

0 commit comments

Comments
 (0)