/* This file is part of Libelfpp. Libelfpp is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Libelfpp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Libelfpp. If not, see . Copyright (c) Alexandre Becoulet */ #include #include #include #include #include #include #include #include #include #include namespace elfpp { section::section(object &obj, sh_type_e type) : name_(), type_(type), flags_(SHF_NONE), vaddr_(0), size_(0), link_(0), info_(0), align_(0), entsize_(0), index_(0), back_info_(0), back_link_(0), object_(&obj), content_(0), sym_tab_() { } section::~section() { if (!orphan()) remove(); if (content_) free(content_); object_->secidx_[index_] = 0; FOREACH(s, sym_tab_) delete s->second; } void section::set_size(size_t size) { if (type_ != SHT_NOBITS && size_ != size) { content_ = (uint8_t*)realloc(content_, size); assert(content_ || size == 0); if (size > size_) std::memset(content_ + size_, 0, size - size_); } size_ = size; } void section::set_content(void* a) { if(content_) free(content_); content_ = (uint8_t*) a; } void section::add_symbol(symbol &sym) { sym_tab_.insert(sym_tab_map_t::value_type(sym.get_name(), &sym)); } symbol & section::get_symbol(uint64_t offset) { symbol *res = 0; FOREACH(i, get_symbol_table()) { symbol *j = i->second; if (!j->get_size()) continue; if (j->get_value() <= offset && (!res || j->get_value() > res->get_value())) res = j; } if (!res) throw std::runtime_error("no symbol found"); if (offset - res->get_value() >= res->get_size()) throw std::runtime_error("offset above symbol size"); return *res; } segment * section::get_segment() const { if (!object_) throw std::runtime_error("section is not part of an object"); // find associated segment based on section content in elf file FOREACH(s, object_->get_segment_table()) { if (get_file_offset() >= s->get_file_offset() && get_file_offset() < s->get_file_offset() + (off_t)s->get_file_size()) return &*s; } return 0; } uint64_t section::get_load_address() const { segment *s = get_segment(); if (!s) throw std::runtime_error("section is not located in a segment"); return vaddr_ - s->get_vaddr() + s->get_paddr(); } std::ostream & operator<<(std::ostream &o, const section &s) { o << "[" << s.name_ << " addr:0x" << std::hex << s.vaddr_ << " size:" << std::dec << s.size_ << "]"; return o; } }