Skip to content

Commit 81440ce

Browse files
committed
Enhance ELF API the DynamicEntryArray
1 parent c375a47 commit 81440ce

File tree

4 files changed

+102
-2
lines changed

4 files changed

+102
-2
lines changed

api/python/ELF/objects/pyDynamicEntryArray.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,36 @@ void init_ELF_DynamicEntryArray_class(py::module& m) {
4545
"Return the array",
4646
py::return_value_policy::reference)
4747

48+
.def("insert",
49+
&DynamicEntryArray::insert,
50+
"Insert a ``callback`` at the given ``position``",
51+
"position"_a, "callback"_a,
52+
py::return_value_policy::reference)
53+
54+
.def("append",
55+
&DynamicEntryArray::append,
56+
"Append the given ``callback`` ",
57+
"callback"_a,
58+
py::return_value_policy::reference)
59+
60+
.def("remove",
61+
&DynamicEntryArray::remove,
62+
"Remove the given ``callback`` ",
63+
"callback"_a,
64+
py::return_value_policy::reference)
65+
66+
67+
.def(py::self += uint64_t())
68+
.def(py::self -= uint64_t())
69+
70+
71+
.def("__getitem__",
72+
static_cast<uint64_t& (DynamicEntryArray::*)(size_t)>(&DynamicEntryArray::operator[]),
73+
py::return_value_policy::reference)
74+
75+
.def("__len__",
76+
&DynamicEntryArray::size)
77+
4878
.def("__eq__", &DynamicEntryArray::operator==)
4979
.def("__ne__", &DynamicEntryArray::operator!=)
5080
.def("__hash__",

include/LIEF/ELF/DynamicEntryArray.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ class DLL_PUBLIC DynamicEntryArray : public DynamicEntry {
3939
const std::vector<uint64_t>& array(void) const;
4040
virtual void array(const std::vector<uint64_t>& array) override;
4141

42+
//! @brief Insert the given callback at ``pos``
43+
DynamicEntryArray& insert(size_t pos, uint64_t callback);
44+
45+
//! @brief Append the given callback
46+
DynamicEntryArray& append(uint64_t callback);
47+
48+
//! @brief Remove the given callback
49+
DynamicEntryArray& remove(uint64_t callback);
50+
51+
//! @brief Number of callback registred
52+
size_t size(void) const;
53+
54+
DynamicEntryArray& operator+=(uint64_t value);
55+
DynamicEntryArray& operator-=(uint64_t value);
56+
57+
const uint64_t& operator[](size_t idx) const;
58+
uint64_t& operator[](size_t idx);
59+
4260
//! @brief Method so that the ``visitor`` can visit us
4361
virtual void accept(Visitor& visitor) const override;
4462

src/ELF/DynamicEntryArray.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,57 @@ void DynamicEntryArray::array(const std::vector<uint64_t>& array) {
4646
this->array_ = array;
4747
}
4848

49+
DynamicEntryArray& DynamicEntryArray::append(uint64_t value) {
50+
this->array_.push_back(value);
51+
return *this;
52+
}
53+
54+
DynamicEntryArray& DynamicEntryArray::remove(uint64_t callback) {
55+
this->array_.erase(std::remove_if(
56+
std::begin(this->array_),
57+
std::end(this->array_),
58+
[callback] (uint64_t v) {
59+
return v == callback;
60+
}), std::end(this->array_));
61+
return *this;
62+
}
63+
64+
DynamicEntryArray& DynamicEntryArray::insert(size_t pos, uint64_t value) {
65+
if (pos == this->array_.size()) {
66+
return this->append(value);
67+
}
68+
69+
if (pos > this->array_.size()) {
70+
throw corrupted(std::to_string(pos) + " is out of ranges");
71+
}
72+
this->array_.insert(std::begin(this->array_) + pos, value);
73+
return *this;
74+
}
75+
76+
77+
size_t DynamicEntryArray::size(void) const {
78+
return this->array_.size();
79+
}
80+
81+
DynamicEntryArray& DynamicEntryArray::operator+=(uint64_t value) {
82+
return this->append(value);
83+
}
84+
85+
DynamicEntryArray& DynamicEntryArray::operator-=(uint64_t value) {
86+
return this->remove(value);
87+
}
88+
89+
const uint64_t& DynamicEntryArray::operator[](size_t idx) const {
90+
if (idx >= this->array_.size()) {
91+
throw corrupted(std::to_string(idx) + " is out of ranges");
92+
}
93+
return this->array_[idx];
94+
}
95+
96+
uint64_t& DynamicEntryArray::operator[](size_t idx) {
97+
return const_cast<uint64_t&>(static_cast<const DynamicEntryArray*>(this)->operator[](idx));
98+
}
99+
49100
void DynamicEntryArray::accept(Visitor& visitor) const {
50101
DynamicEntry::accept(visitor);
51102
visitor(*this); // Double dispatch to avoid down-casting

tests/elf/test_dynamic.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ def setUp(self):
132132
self.logger = logging.getLogger(__name__)
133133

134134

135+
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
135136
def test_remove_library(self):
136137
sample = LibAddSample()
137138
libadd = lief.parse(sample.libadd)
@@ -142,6 +143,7 @@ def test_remove_library(self):
142143
self.assertFalse(binadd.has_library("libadd.so"))
143144

144145

146+
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
145147
def test_remove_tag(self):
146148
sample = LibAddSample()
147149
libadd = lief.parse(sample.libadd)
@@ -157,6 +159,7 @@ def test_remove_tag(self):
157159

158160
self.assertTrue(all(e.tag != lief.ELF.DYNAMIC_TAGS.NEEDED for e in binadd.dynamic_entries))
159161

162+
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
160163
def test_runpath_api(self):
161164
sample = LibAddSample()
162165
libadd = lief.parse(sample.libadd)
@@ -196,8 +199,6 @@ def test_runpath_api(self):
196199

197200
self.assertEqual(rpath.runpath, "")
198201

199-
200-
201202
self.logger.debug(rpath)
202203

203204

0 commit comments

Comments
 (0)