From b5be3bb5b05061772e849309c625e92a6421c798 Mon Sep 17 00:00:00 2001 From: Robin Nicholson Date: Thu, 15 Mar 2018 19:56:25 +0100 Subject: [PATCH] Support for better syntax --- Section.h | 124 ++++++++++++++++++++++++++++++++++++++++++++++ SectionHeader.cpp | 22 ++++++++ SectionHeader.h | 70 ++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 Section.h create mode 100644 SectionHeader.cpp create mode 100644 SectionHeader.h diff --git a/Section.h b/Section.h new file mode 100644 index 0000000..8b8faf7 --- /dev/null +++ b/Section.h @@ -0,0 +1,124 @@ +#ifndef ELFSPY_SECTION_H +#define ELFSPY_SECTION_H + +#include +#include + +namespace spy +{ +#ifdef __x86_64__ +using Elf_Shdr = Elf64_Shdr; +#else +using Elf_Shdr = Elf32_Shdr; +#endif +class SectionHeader; + +template +class Section +{ +public: + class Iterator; + Iterator begin() const; + Iterator end() const; + size_t entries() const; + const T& operator[](size_t index) const; + +private: + const unsigned char* data_; + const Elf_Shdr* header_; + friend class SectionHeader; + Section(const unsigned char* data, const Elf_Shdr* header); +}; + +template +inline Section::Section(const unsigned char* data, const Elf_Shdr* header) + :data_(data) + ,header_(header) +{ +} + +template +class Section::Iterator +{ +public: + Iterator& operator++(); + Iterator operator++(int); + const T& operator*() const; + const T* operator->() const; + bool operator!=(const Iterator& other) const; + +private: + Iterator(const unsigned char* data, size_t size); + const unsigned char* data_; + size_t size_; + friend class Section; +}; + +template +inline Section::Iterator::Iterator(const unsigned char* data, size_t size) +{ + data_ = data; + size_ = size; +} + +template +inline typename Section::Iterator& Section::Iterator::operator++() +{ + data_ += size_; + return *this; +} + +template +inline typename Section::Iterator Section::Iterator::operator++(int) +{ + Iterator copy(*this); + data_ += size_; + return copy; +} + +template +inline const T& Section::Iterator::operator*() const +{ + return *reinterpret_cast(data_); +} + +template +inline const T* Section::Iterator::operator->() const +{ + return reinterpret_cast(data_); +} + +template +inline bool Section::Iterator::operator!=(const Section::Iterator& other) const +{ + return data_ != other.data_; +} + +template +inline typename Section::Iterator Section::begin() const +{ + return { data_ + header_->sh_offset, header_->sh_entsize }; +} + +template +inline typename Section::Iterator Section::end() const +{ + return { data_ + header_->sh_offset + header_->sh_size, header_->sh_entsize }; +} + +template +inline size_t Section::entries() const +{ + return header_->sh_size / header_->sh_entsize; +} + +template +const T& Section::operator[](size_t index) const +{ + index *= header_->sh_entsize; + return *reinterpret_cast(data_ + header_->sh_offset + index); +} + +} // namespace spy + +#endif diff --git a/SectionHeader.cpp b/SectionHeader.cpp new file mode 100644 index 0000000..30e2e1f --- /dev/null +++ b/SectionHeader.cpp @@ -0,0 +1,22 @@ +#include "elfspy/SectionHeader.h" + +#include + +namespace +{ +spy::Elf_Shdr no_header() +{ + spy::Elf_Shdr zero_init; + memset(&zero_init, 0, sizeof(zero_init)); + return zero_init; +} + +} // namespace + +namespace spy +{ + +// allow begin() and end() to work with SectionHeaders that were not found +const Elf_Shdr SectionHeader::no_header_ = no_header(); + +} // namespace spy diff --git a/SectionHeader.h b/SectionHeader.h new file mode 100644 index 0000000..a5e8d52 --- /dev/null +++ b/SectionHeader.h @@ -0,0 +1,70 @@ +#ifndef ELFSPY_SECTIONHEADER_H +#define ELFSPY_SECTIONHEADER_H + +#include +#include "elfspy/Section.h" + +namespace spy +{ +class ELFInfo; + +class SectionHeader +{ +public: + SectionHeader() = default; + const unsigned char* begin() const; + const unsigned char* end() const; + size_t entries() const; + bool operator!() const; + explicit operator bool() const; + template + Section as_section() const; +private: + static const Elf_Shdr no_header_; + const unsigned char* data_ = nullptr; + const Elf_Shdr* header_ = &no_header_; + friend class ELFInfo; + SectionHeader(const unsigned char* data, const Elf_Shdr* header); +}; + +inline SectionHeader::SectionHeader(const unsigned char* data, const Elf_Shdr* header) + :data_(data) + ,header_(header) +{ +} + +inline const unsigned char* SectionHeader::begin() const +{ + return data_ + header_->sh_offset; +} + +inline const unsigned char* SectionHeader::end() const +{ + return begin() + header_->sh_size; +} + + +inline size_t SectionHeader::entries() const +{ + return header_->sh_size / header_->sh_entsize; +} + +inline bool SectionHeader::operator!() const +{ + return header_ == nullptr; +} + +inline SectionHeader::operator bool() const +{ + return header_ != nullptr; +} + +template +inline Section SectionHeader::as_section() const +{ + return { data_, header_ }; +} + +} // namespace spy + +#endif