#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