Add applies_to field to Relocation

The field contains a pointer to the Section object
the OBJECT Relocation applies to.
This commit is contained in:
yd0b0N 2018-04-20 10:42:04 +02:00 committed by Romain Thomas
parent 55e99450f4
commit 0bbeaa81e9
6 changed files with 71 additions and 15 deletions

View File

@ -62,6 +62,15 @@ void init_ELF_Relocation_class(py::module& m) {
"" RST_CLASS_REF(lief.ELF.Symbol) " associated with the relocation",
py::return_value_policy::reference_internal)
.def_property_readonly("has_section",
&Relocation::has_section,
"``True`` if a this relocation has a " RST_CLASS_REF(lief.ELF.Section) " associated")
.def_property_readonly("section",
static_cast<Section& (Relocation::*)(void)>(&Relocation::section),
"" RST_CLASS_REF(lief.ELF.Section) " to which the relocation applies",
py::return_value_policy::reference)
.def_property_readonly("is_rela",
static_cast<getter_t<bool>>(&Relocation::is_rela),
"``True`` if the relocation uses the :attr:`~lief.ELF.Relocation.addend` proprety")

View File

@ -181,7 +181,7 @@ class LIEF_API Parser : public LIEF::Parser {
//! use parse relocations by using LIEF::ELF::Segment. This method parse relocations
//! that are not reachable through segments (For example Object file).
template<typename ELF_T, typename REL_T>
void parse_section_relocations(uint64_t offset, uint64_t size);
void parse_section_relocations(uint64_t offset, uint64_t size, Section *applies_to = nullptr);
//! @brief Parse SymbolVersionRequirement
//!

View File

@ -77,6 +77,13 @@ class LIEF_API Relocation : public LIEF::Relocation {
Symbol& symbol(void);
const Symbol& symbol(void) const;
//! True if the relocation has a section associated
bool has_section(void) const;
//! Section associated with this relocation
Section& section(void);
const Section& section(void) const;
//void address(uint64_t address);
void addend(int64_t addend);
void type(uint32_t type);
@ -93,9 +100,10 @@ class LIEF_API Relocation : public LIEF::Relocation {
uint32_t type_;
int64_t addend_;
bool isRela_;
Symbol* symbol_;
Symbol* symbol_{nullptr};
ARCH architecture_;
RELOCATION_PURPOSES purpose_;
Section* section_{nullptr};
};

View File

@ -418,15 +418,21 @@ void Parser::parse_binary(void) {
// Try to parse using sections
if (this->binary_->relocations_.size() == 0) {
for (const Section& section : this->binary_->sections()) {
Section* section_associated = nullptr;
if (section.information() > 0 and section.information() < this->binary_->sections_.size()) {
const size_t sh_info = section.information();
section_associated = this->binary_->sections_[sh_info];
}
try {
if (section.type() == ELF_SECTION_TYPES::SHT_REL) {
this->parse_section_relocations<ELF_T, typename ELF_T::Elf_Rel>(
section.file_offset(), section.size());
this->parse_section_relocations<ELF_T, typename ELF_T::Elf_Rel>(
section.file_offset(), section.size(), section_associated);
}
else if (section.type() == ELF_SECTION_TYPES::SHT_RELA) {
this->parse_section_relocations<ELF_T, typename ELF_T::Elf_Rela>(
section.file_offset(), section.size());
section.file_offset(), section.size(), section_associated);
}
} catch (const exception& e) {
@ -1319,9 +1325,12 @@ void Parser::parse_pltgot_relocations(uint64_t offset, uint64_t size) {
}
template<typename ELF_T, typename REL_T>
void Parser::parse_section_relocations(uint64_t offset, uint64_t size) {
static_assert(std::is_same<REL_T, typename ELF_T::Elf_Rel>::value or
std::is_same<REL_T, typename ELF_T::Elf_Rela>::value, "REL_T must be Elf_Rel or Elf_Rela");
void Parser::parse_section_relocations(uint64_t offset, uint64_t size, Section *applies_to) {
using Elf_Rel = typename ELF_T::Elf_Rel;
using Elf_Rela = typename ELF_T::Elf_Rela;
static_assert(std::is_same<REL_T, Elf_Rel>::value or
std::is_same<REL_T, Elf_Rela>::value, "REL_T must be Elf_Rel or Elf_Rela");
const uint64_t offset_relocations = offset;
const uint8_t shift = std::is_same<ELF_T, ELF32>::value ? 8 : 32;
@ -1338,6 +1347,7 @@ void Parser::parse_section_relocations(uint64_t offset, uint64_t size) {
std::unique_ptr<Relocation> reloc{new Relocation{&rel_hdr}};
reloc->architecture_ = this->binary_->header_.machine_type();
reloc->section_ = applies_to;
if (this->binary_->header().file_type() == ELF::E_TYPE::ET_REL and
this->binary_->segments().size() == 0) {
reloc->purpose(RELOCATION_PURPOSES::RELOC_PURPOSE_OBJECT);

View File

@ -36,7 +36,8 @@ Relocation::Relocation(void) :
isRela_{false},
symbol_{nullptr},
architecture_{ARCH::EM_NONE},
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE}
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE},
section_{nullptr}
{}
@ -47,7 +48,8 @@ Relocation::Relocation(const Relocation& other) :
isRela_{other.isRela_},
symbol_{nullptr},
architecture_{other.architecture_},
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE}
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE},
section_{nullptr}
{
}
@ -64,7 +66,8 @@ Relocation::Relocation(const Elf32_Rel* header) :
isRela_{false},
symbol_{nullptr},
architecture_{ARCH::EM_NONE},
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE}
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE},
section_{nullptr}
{}
@ -75,7 +78,8 @@ Relocation::Relocation(const Elf32_Rela* header) :
isRela_{true},
symbol_{nullptr},
architecture_{ARCH::EM_NONE},
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE}
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE},
section_{nullptr}
{}
@ -86,7 +90,8 @@ Relocation::Relocation(const Elf64_Rel* header) :
isRela_{false},
symbol_{nullptr},
architecture_{ARCH::EM_NONE},
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE}
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE},
section_{nullptr}
{}
@ -97,7 +102,8 @@ Relocation::Relocation(const Elf64_Rela* header) :
isRela_{true},
symbol_{nullptr},
architecture_{ARCH::EM_NONE},
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE}
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE},
section_{nullptr}
{}
@ -108,7 +114,8 @@ Relocation::Relocation(uint64_t address, uint32_t type, int64_t addend, bool isR
isRela_{isRela},
symbol_{nullptr},
architecture_{ARCH::EM_NONE},
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE}
purpose_{RELOCATION_PURPOSES::RELOC_PURPOSE_NONE},
section_{nullptr}
{}
@ -120,6 +127,7 @@ void Relocation::swap(Relocation& other) {
std::swap(this->symbol_, other.symbol_);
std::swap(this->architecture_, other.architecture_);
std::swap(this->purpose_, other.purpose_);
std::swap(this->section_, other.section_);
}
int64_t Relocation::addend(void) const {
@ -144,6 +152,17 @@ Symbol& Relocation::symbol(void) {
return const_cast<Symbol&>(static_cast<const Relocation*>(this)->symbol());
}
const Section& Relocation::section(void) const {
if (this->has_section()) {
return *this->section_;
} else {
throw not_found("No section associated with this relocation");
}
}
Section& Relocation::section(void) {
return const_cast<Section&>(static_cast<const Relocation*>(this)->section());
}
bool Relocation::is_rela(void) const {
return this->isRela_;
@ -169,6 +188,10 @@ bool Relocation::has_symbol(void) const {
return this->symbol_ != nullptr;
}
bool Relocation::has_section(void) const {
return this->section_ != nullptr;
}
size_t Relocation::size(void) const {
switch (this->architecture()) {

View File

@ -318,6 +318,7 @@ void JsonVisitor::visit(const Symbol& symbol) {
void JsonVisitor::visit(const Relocation& relocation) {
std::string relocation_type = "NOT_TO_STRING";
std::string symbol_name = "";
std::string section_name = "";
if (relocation.has_symbol()) {
const Symbol& s = relocation.symbol();
@ -328,6 +329,10 @@ void JsonVisitor::visit(const Relocation& relocation) {
}
}
if (relocation.has_section()) {
section_name = relocation.section().name();
}
if (relocation.architecture() == ARCH::EM_X86_64) {
relocation_type = to_string(static_cast<RELOC_x86_64>(relocation.type()));
@ -336,6 +341,7 @@ void JsonVisitor::visit(const Relocation& relocation) {
this->node_["symbol_name"] = symbol_name;
this->node_["address"] = relocation.address();
this->node_["type"] = relocation_type;
this->node_["section"] = section_name;
}