Skip to content
Permalink
Browse files
Improve API for ELF RUN_PATH / RPATH
  • Loading branch information
romainthomas committed Sep 12, 2017
1 parent 1e410e6 commit c375a47
Show file tree
Hide file tree
Showing 7 changed files with 307 additions and 6 deletions.
@@ -37,7 +37,12 @@ void init_ELF_DynamicEntryRpath_class(py::module& m) {
py::class_<DynamicEntryRpath, DynamicEntry>(m, "DynamicEntryRpath")
.def(py::init<const std::string &>(),
"Constructor from (r)path",
"path"_a)
"path"_a = "")

.def(py::init<const std::vector<std::string> &>(),
"Constructor from a list of paths",
"paths"_a)

.def_property("name",
[] (const DynamicEntryRpath& obj) {
return safe_string_converter(obj.name());
@@ -52,6 +57,34 @@ void init_ELF_DynamicEntryRpath_class(py::module& m) {
static_cast<setter_t<const std::string&>>(&DynamicEntryRpath::rpath),
"Return path value")


.def_property("paths",
static_cast<getter_t<std::vector<std::string> >>(&DynamicEntryRpath::paths),
static_cast<setter_t<const std::vector<std::string>&>>(&DynamicEntryRpath::paths),
"Paths as a list")

.def("insert",
&DynamicEntryRpath::insert,
"Insert a ``path`` at the given ``position``",
"position"_a, "path"_a,
py::return_value_policy::reference)

.def("append",
&DynamicEntryRpath::append,
"Append the given ``path`` ",
"path"_a,
py::return_value_policy::reference)


.def("remove",
&DynamicEntryRpath::remove,
"Remove the given ``path`` ",
"path"_a,
py::return_value_policy::reference)

.def(py::self += std::string())
.def(py::self -= std::string())

.def("__eq__", &DynamicEntryRpath::operator==)
.def("__ne__", &DynamicEntryRpath::operator!=)
.def("__hash__",
@@ -37,21 +37,53 @@ void init_ELF_DynamicEntryRunPath_class(py::module& m) {
py::class_<DynamicEntryRunPath, DynamicEntry>(m, "DynamicEntryRunPath")
.def(py::init<const std::string &>(),
"Constructor from (run)path",
"path"_a)
"path"_a = "")

.def(py::init<const std::vector<std::string> &>(),
"Constructor from a list of paths",
"paths"_a)

.def_property("name",
[] (const DynamicEntryRunPath& obj) {
return safe_string_converter(obj.name());
},
static_cast<setter_t<const std::string&>>(&DynamicEntryRunPath::name),
"Return path value")
"Runpath raw value")

.def_property("runpath",
[] (const DynamicEntryRunPath& obj) {
return safe_string_converter(obj.runpath());
},
static_cast<setter_t<const std::string&>>(&DynamicEntryRunPath::runpath),
"Return path value")
"Runpath raw value")

.def_property("paths",
static_cast<getter_t<std::vector<std::string> >>(&DynamicEntryRunPath::paths),
static_cast<setter_t<const std::vector<std::string>&>>(&DynamicEntryRunPath::paths),
"Paths as a list")

.def("insert",
&DynamicEntryRunPath::insert,
"Insert a ``path`` at the given ``position``",
"position"_a, "path"_a,
py::return_value_policy::reference)

.def("append",
&DynamicEntryRunPath::append,
"Append the given ``path`` ",
"path"_a,
py::return_value_policy::reference)


.def("remove",
&DynamicEntryRunPath::remove,
"Remove the given ``path`` ",
"path"_a,
py::return_value_policy::reference)


.def(py::self += std::string())
.def(py::self -= std::string())

.def("__eq__", &DynamicEntryRunPath::operator==)
.def("__ne__", &DynamicEntryRunPath::operator!=)
@@ -28,6 +28,7 @@ namespace ELF {
class DLL_PUBLIC DynamicEntryRpath : public DynamicEntry {

public:
static constexpr char delimiter = ':';
using DynamicEntry::DynamicEntry;

DynamicEntryRpath(const Elf64_Dyn* header);
@@ -36,6 +37,9 @@ class DLL_PUBLIC DynamicEntryRpath : public DynamicEntry {

DynamicEntryRpath(const std::string& name = "");

//! @brief Constructor from a list of paths
DynamicEntryRpath(const std::vector<std::string>& paths);

DynamicEntryRpath& operator=(const DynamicEntryRpath&);
DynamicEntryRpath(const DynamicEntryRpath&);

@@ -45,6 +49,22 @@ class DLL_PUBLIC DynamicEntryRpath : public DynamicEntry {
const std::string& rpath(void) const;
void rpath(const std::string& name);

//! @brief Paths as a list
std::vector<std::string> paths(void) const;
void paths(const std::vector<std::string>& paths);

//! @brief Insert a ``path`` at the given ``position``
DynamicEntryRpath& insert(size_t pos, const std::string path);

//! @brief Append the given ``path``
DynamicEntryRpath& append(const std::string& path);

//! @brief Remove the given ``path``
DynamicEntryRpath& remove(const std::string& path);

DynamicEntryRpath& operator+=(const std::string& path);
DynamicEntryRpath& operator-=(const std::string& path);

virtual void accept(Visitor& visitor) const override;

virtual std::ostream& print(std::ostream& os) const override;
@@ -27,23 +27,46 @@ namespace ELF {
class DLL_PUBLIC DynamicEntryRunPath : public DynamicEntry {

public:
static constexpr char delimiter = ':';
using DynamicEntry::DynamicEntry;

DynamicEntryRunPath(const Elf64_Dyn* header);
DynamicEntryRunPath(const Elf32_Dyn* header);
DynamicEntryRunPath(void);

//! @brief Constructor from (run)path
DynamicEntryRunPath(const std::string& name = "");

//! @brief Constructor from a list of paths
DynamicEntryRunPath(const std::vector<std::string>& paths);

DynamicEntryRunPath& operator=(const DynamicEntryRunPath&);
DynamicEntryRunPath(const DynamicEntryRunPath&);

//! @brief Runpath raw value
virtual const std::string& name(void) const override;
virtual void name(const std::string& name) override;

//! @brief Runpath raw value
const std::string& runpath(void) const;
void runpath(const std::string& runpath);

//! @brief Paths as a list
std::vector<std::string> paths(void) const;
void paths(const std::vector<std::string>& paths);

//! @brief Insert a ``path`` at the given ``position``
DynamicEntryRunPath& insert(size_t pos, const std::string path);

//! @brief Append the given ``path``
DynamicEntryRunPath& append(const std::string& path);

//! @brief Remove the given ``path``
DynamicEntryRunPath& remove(const std::string& path);

DynamicEntryRunPath& operator+=(const std::string& path);
DynamicEntryRunPath& operator-=(const std::string& path);

virtual void accept(Visitor& visitor) const override;

virtual std::ostream& print(std::ostream& os) const override;
@@ -16,6 +16,8 @@
#include "LIEF/ELF/DynamicEntryRpath.hpp"

#include <iomanip>
#include <numeric>
#include <sstream>

namespace LIEF {
namespace ELF {
@@ -39,6 +41,14 @@ DynamicEntryRpath::DynamicEntryRpath(const std::string& rpath) :
{
}


DynamicEntryRpath::DynamicEntryRpath(const std::vector<std::string>& paths) :
DynamicEntry::DynamicEntry{DYNAMIC_TAGS::DT_RPATH, 0},
rpath_{""}
{
this->paths(paths);
}

const std::string& DynamicEntryRpath::name(void) const {
return this->rpath_;
}
@@ -57,6 +67,70 @@ void DynamicEntryRpath::rpath(const std::string& rpath) {
this->name(rpath);
}


std::vector<std::string> DynamicEntryRpath::paths(void) const {
std::stringstream ss;
ss.str(this->rpath());
std::string path;
std::vector<std::string> paths;
while (std::getline(ss, path, DynamicEntryRpath::delimiter)) {
paths.push_back(path);
}
return paths;
}

void DynamicEntryRpath::paths(const std::vector<std::string>& paths) {
this->rpath_ = std::accumulate(
std::begin(paths),
std::end(paths),
std::string(""),
[] (std::string path, const std::string& new_entry) {
return path.empty() ? new_entry : path + DynamicEntryRpath::delimiter + new_entry;
});
}

DynamicEntryRpath& DynamicEntryRpath::append(const std::string& path) {
std::vector<std::string> paths = this->paths();
paths.push_back(path);
this->paths(paths);
return *this;
}

DynamicEntryRpath& DynamicEntryRpath::remove(const std::string& path) {
std::vector<std::string> paths = this->paths();
paths.erase(std::remove_if(
std::begin(paths),
std::end(paths),
[&path] (const std::string& p) {
return p == path;
}), std::end(paths));
this->paths(paths);
return *this;
}

DynamicEntryRpath& DynamicEntryRpath::insert(size_t pos, const std::string path) {
std::vector<std::string> paths = this->paths();

if (pos == paths.size()) {
return this->append(path);
}

if (pos > paths.size()) {
throw corrupted(std::to_string(pos) + " is out of ranges");
}
paths.insert(std::begin(paths) + pos, path);
this->paths(paths);
return *this;
}

DynamicEntryRpath& DynamicEntryRpath::operator+=(const std::string& path) {
return this->append(path);
}

DynamicEntryRpath& DynamicEntryRpath::operator-=(const std::string& path) {
return this->remove(path);
}

void DynamicEntryRpath::accept(Visitor& visitor) const {
DynamicEntry::accept(visitor);
visitor(*this); // Double dispatch to avoid down-casting
@@ -16,6 +16,8 @@
#include "LIEF/ELF/DynamicEntryRunPath.hpp"

#include <iomanip>
#include <numeric>
#include <sstream>

namespace LIEF {
namespace ELF {
@@ -39,6 +41,16 @@ DynamicEntryRunPath::DynamicEntryRunPath(const std::string& runpath) :
{
}


DynamicEntryRunPath::DynamicEntryRunPath(const std::vector<std::string>& paths) :
DynamicEntry::DynamicEntry{DYNAMIC_TAGS::DT_RUNPATH, 0},
runpath_{""}
{
this->paths(paths);
}



const std::string& DynamicEntryRunPath::name(void) const {
return this->runpath_;
}
@@ -52,11 +64,74 @@ const std::string& DynamicEntryRunPath::runpath(void) const {
return this->name();
}


void DynamicEntryRunPath::runpath(const std::string& runpath) {
this->name(runpath);
}


std::vector<std::string> DynamicEntryRunPath::paths(void) const {
std::stringstream ss;
ss.str(this->runpath());
std::string path;
std::vector<std::string> paths;
while (std::getline(ss, path, DynamicEntryRunPath::delimiter)) {
paths.push_back(path);
}
return paths;
}

void DynamicEntryRunPath::paths(const std::vector<std::string>& paths) {
this->runpath_ = std::accumulate(
std::begin(paths),
std::end(paths),
std::string(""),
[] (std::string path, const std::string& new_entry) {
return path.empty() ? new_entry : path + DynamicEntryRunPath::delimiter + new_entry;
});
}

DynamicEntryRunPath& DynamicEntryRunPath::append(const std::string& path) {
std::vector<std::string> paths = this->paths();
paths.push_back(path);
this->paths(paths);
return *this;
}

DynamicEntryRunPath& DynamicEntryRunPath::remove(const std::string& path) {
std::vector<std::string> paths = this->paths();
paths.erase(std::remove_if(
std::begin(paths),
std::end(paths),
[&path] (const std::string& p) {
return p == path;
}), std::end(paths));
this->paths(paths);
return *this;
}

DynamicEntryRunPath& DynamicEntryRunPath::insert(size_t pos, const std::string path) {
std::vector<std::string> paths = this->paths();

if (pos == paths.size()) {
return this->append(path);
}

if (pos > paths.size()) {
throw corrupted(std::to_string(pos) + " is out of ranges");
}
paths.insert(std::begin(paths) + pos, path);
this->paths(paths);
return *this;
}

DynamicEntryRunPath& DynamicEntryRunPath::operator+=(const std::string& path) {
return this->append(path);
}

DynamicEntryRunPath& DynamicEntryRunPath::operator-=(const std::string& path) {
return this->remove(path);
}

void DynamicEntryRunPath::accept(Visitor& visitor) const {
DynamicEntry::accept(visitor);
visitor(*this); // Double dispatch to avoid down-casting

0 comments on commit c375a47

Please sign in to comment.