Skip to content

Commit

Permalink
Improve API of ELF's Section
Browse files Browse the repository at this point in the history
API changes:
  - 'has_flag' renamed to 'has'
  - 'add_flag' renamed to 'add'
  - 'remove_flag' renamed to 'remove'
  - operator+= to add a flag - added
  - operator-= to remove a flag - added
  - 'has' for Segment object - added
  • Loading branch information
romainthomas committed Aug 2, 2017
1 parent 4425292 commit 43bd06f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 16 deletions.
41 changes: 36 additions & 5 deletions api/python/ELF/objects/pySection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,30 @@ void init_ELF_Section_class(py::module& m) {
"Return segment(s) associated with the given section",
py::return_value_policy::reference_internal)

.def("__contains__",
[] (const Section &section, SECTION_FLAGS flag)
{
return section.has_flag(flag);
}, "Test if the current section has the given flag")

.def("add",
&Section::add,
"Add the given " RST_CLASS_REF(lief.ELF.SECTION_FLAGS) " to the list of "
":attr:`~lief.ELF.Section.flags`",
"flag"_a)

.def("remove",
&Section::remove,
"Remove the given " RST_CLASS_REF(lief.ELF.SECTION_FLAGS) " to the list of "
":attr:`~lief.ELF.Section.flags`",
"flag"_a)


.def("has",
static_cast<bool (Section::*)(SECTION_FLAGS) const>(&Section::has),
"Check if the given " RST_CLASS_REF(lief.ELF.SECTION_FLAGS) " is present",
"flag"_a)

.def("has",
static_cast<bool (Section::*)(const Segment&) const>(&Section::has),
"Check if the given " RST_CLASS_REF(lief.ELF.Segment) " is present "
"in :attr:`~lief.ELF.Section.segments`",
"segment"_a)

.def("__eq__", &Section::operator==)
.def("__ne__", &Section::operator!=)
Expand All @@ -117,6 +135,19 @@ void init_ELF_Section_class(py::module& m) {
return LIEF::Hash::hash(section);
})

.def(py::self += SECTION_FLAGS())
.def(py::self -= SECTION_FLAGS())

.def("__contains__",
static_cast<bool (Section::*)(SECTION_FLAGS) const>(&Section::has),
"Check if the given " RST_CLASS_REF(lief.ELF.SECTION_FLAGS) " is present")


.def("__contains__",
static_cast<bool (Section::*)(const Segment&) const>(&Section::has),
"Check if the given " RST_CLASS_REF(lief.ELF.Segment) " is present "
"in :attr:`~lief.ELF.Section.segments`")

.def("__str__",
[] (const Section& section)
{
Expand Down
13 changes: 10 additions & 3 deletions include/LIEF/ELF/Section.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ class DLL_PUBLIC Section : public LIEF::Section {
//! @brief ``True`` if the section has the given flag
//!
//! @param[in] flag flag to test
bool has_flag(SECTION_FLAGS flag) const;
bool has(SECTION_FLAGS flag) const;

//! @brief ``True`` if the section is in the given segment
bool has(const Segment& segment) const;

//! @brief Return section flags as a ``std::set``
std::set<SECTION_FLAGS> flags_list(void) const;
Expand All @@ -89,10 +92,11 @@ class DLL_PUBLIC Section : public LIEF::Section {
uint32_t link(void) const;


void add(SECTION_FLAGS flag);
void remove(SECTION_FLAGS flag);

void type(SECTION_TYPES type);
void flags(uint64_t flags);
void add_flag(SECTION_FLAGS flag);
void remove_flag(SECTION_FLAGS flag);
void clear_flags(void);
void file_offset(uint64_t offset);
void link(uint32_t link);
Expand All @@ -105,6 +109,9 @@ class DLL_PUBLIC Section : public LIEF::Section {

virtual void accept(Visitor& visitor) const override;

Section& operator+=(SECTION_FLAGS c);
Section& operator-=(SECTION_FLAGS c);

bool operator==(const Section& rhs) const;
bool operator!=(const Section& rhs) const;

Expand Down
40 changes: 32 additions & 8 deletions src/ELF/Section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,21 @@ uint64_t Section::flags(void) const {
return this->flags_;
}

bool Section::has_flag(SECTION_FLAGS flag) const {
return (this->flags_ & static_cast<uint64_t>(flag)) != 0;
bool Section::has(SECTION_FLAGS flag) const {
return (this->flags() & static_cast<uint64_t>(flag)) != 0;
}


bool Section::has(const Segment& segment) const {
it_const_segments segments = this->segments();

auto&& it_segment = std::find_if(
std::begin(segments),
std::end(segments),
[&segment] (const Segment& s) {
return s == segment;
});
return it_segment != std::end(segments);
}

uint64_t Section::file_offset(void) const {
Expand Down Expand Up @@ -206,7 +219,7 @@ std::set<SECTION_FLAGS> Section::flags_list(void) const {
std::begin(section_flags_array),
std::end(section_flags_array),
std::inserter(flags, std::begin(flags)),
std::bind(&Section::has_flag, this, std::placeholders::_1));
std::bind(static_cast<bool (Section::*)(SECTION_FLAGS) const>(&Section::has), this, std::placeholders::_1));

return flags;
}
Expand Down Expand Up @@ -243,16 +256,16 @@ void Section::flags(uint64_t flags) {
this->flags_ = flags;
}

void Section::add_flag(SECTION_FLAGS flag) {
this->flags_ = (this->flags_ | static_cast<uint64_t>(flag));
void Section::add(SECTION_FLAGS flag) {
this->flags(this->flags() | static_cast<uint64_t>(flag));
}

void Section::remove_flag(SECTION_FLAGS flag) {
this->flags_ = (this->flags_ & (~ static_cast<uint64_t>(flag)));
void Section::remove(SECTION_FLAGS flag) {
this->flags(this->flags() & (~ static_cast<uint64_t>(flag)));
}

void Section::clear_flags(void) {
this->flags_ = 0;
this->flags(0);
}

void Section::file_offset(uint64_t offset) {
Expand Down Expand Up @@ -297,6 +310,17 @@ void Section::accept(Visitor& visitor) const {
}


Section& Section::operator+=(SECTION_FLAGS c) {
this->add(c);
return *this;
}

Section& Section::operator-=(SECTION_FLAGS c) {
this->remove(c);
return *this;
}


bool Section::operator==(const Section& rhs) const {
size_t hash_lhs = Hash::hash(*this);
size_t hash_rhs = Hash::hash(rhs);
Expand Down

0 comments on commit 43bd06f

Please sign in to comment.