mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-04-27 21:04:32 +00:00
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:
parent
55e99450f4
commit
0bbeaa81e9
@ -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")
|
||||
|
@ -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
|
||||
//!
|
||||
|
@ -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};
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user